总结对象安全访问处理方案
SegmentFault
共 3244字,需浏览 7分钟
·
2020-11-22 18:42
作者:jump jump
来源:SegmentFault 思否社区
前端数据不可信,后端数据不可知
短路运算符号嗅探
const result = (staff.address && staff.address[0] && staff.address[0].zip) || ''
原理解析
null undefined NaN 0 空字符串
运算符 | 说明 |
---|---|
逻辑与,AND(&& ) | 若第一项可转换为 true ,则返回第二项;否则,返回第一项目。 |
逻辑或,OR | 若第一项可转换为 true ,则返回第一项;否则,返回第二项目。 |
逻辑非,NOT(! ) | 若当前项可转换为 true ,则返回 false ;否则,返回 true |
|| 单元保底值
const EMPTY_OBJ = {}
const result = (((staff || EMPTY_OBJ).address || EMPTY_OBJ)[0] || EMPTY_OBJ).zip || ''
try catch
let result = ''
try {
result = staff.address[0].zip
} catch {
// 错误上报
}
链判断运算符
const reuslt = staff?.address?.[0]?.zip || ''
a?.b
// 等同于
a == null ? undefined : a.b
a?.[x]
// 等同于
a == null ? undefined : a[x]
a?.b()
// 等同于
a == null ? undefined : a.b()
a?.()
// 等同于
a == null ? undefined : a()
手写路径获取
/**
* 根据路径来获取 对象内部属性
* @param obj 对象
* @param path 路径 a.b[1].c
*/
function getObjPropByPath(obj: Record, path: string) {
let tempObj = obj
const keyArr = path.split('.').map(x => x.trim())
let i: number = 0
for (let len = keyArr.length; ilet key = keyArr[i]
// 简单判断是否是数组数据,如果 以 ] 结尾的话
const isFormArray = key.endsWith(']')
let index: number = 0
if (isFormArray) {
const data = key.split('[') ?? []
key = data[0] ?? ''
// 对于 parseInt('12]') => 12
index = parseInt(data[1], 10)
}
if (key in tempObj) {
tempObj = tempObj[key]
if (isFormArray && Array.isArray(tempObj)) {
tempObj = tempObj[index]
if (!tempObj) {
return {}
}
}
} else {
return {}
}
}
if (!tempObj) {
return {}
}
return {
o: tempObj,
k: keyArr[i],
v: tempObj[keyArr[i]]
}
}
// 根据 object对象的path路径获取值。如果解析 value 是 undefined 会以 defaultValue 取代。
// _.get(object, path, [defaultValue])
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c');
// => 3
_.get(object, ['a', '0', 'b', 'c']);
// => 3
_.get(object, 'a.b.c', 'default');
// => 'default'
其他
Null 判断运算符
const result = staff.address && staff.address[0] && staff.address[0].zip ?? ''
评论