Optional Chaining
是个好东西, 可惜现在还处于Stage 1
阶段, 虽然 babel 已经实现了该功能, 但是编辑器, eslint 之类还是不支持, 想用还是遥遥无期
Optional Chaining
的作用, 主要是让开发者告别一堆的&&
:
const obj = {
abc: {
def: {
ghi: '123'
}
}
}
上面的对象, 如果想取最后的123
, 在不确定前面 abc, def 是否为 null, undefined 的情况下, 我们就得这么写:
const str = obj && obj.abc && obj.abc.def && obj.abc.def.ghi
天长地久的一串, 但是有Optional Chaining
之后, 你只需要这么写:
const str = obj?.abc?.def?.ghi
是不是简单了很多...
既然Optional Chaining
还用不了, 就自己写个简单的曲线救国的方法:
const oc = (props, property, def) => {
// 如果props不是对象, 则直接返回原值
if (Object.prototype.toString.call(props) !== '[object Object]') return props
// 如果property不是字符串, 则直接返回原值
if (!property || typeof property !== 'string') return props
const arrProperty = property.split('.')
const $return = arrProperty.reduce((prev, curr) => {
if (prev === null || prev === undefined) return
if (Object.prototype.toString.call(prev) === '[object Object]') return prev[curr]
}, props)
return def && $return === undefined ? def : $return
}
var obj = {
abc: {
def: {
ghi: '123'
}
}
}
oc(obj, 'abc')
// 输出:
/*
{
def: {
ghi: '123'
}
}
*/
oc(obj, 'xyz') // 输出 undefined
oc(obj, 'abc.def')
// 输出:
/*
{
ghi: '123'
}
*/
oc(obj, 'abc.def.ghi') // 输出 '123'
var obj = {
abc: {
def: [{
ghi: '123'
}]
}
}
oc(obj, 'abc.def.ghi') // 输出 undefined
oc(obj, 'abc.def.ghi', {}) // 输出 {}
oc(obj, 'abc.def.0.ghi') // 输出 '123'
oc(obj, 'abc.def.length') // 输出 1
var a = {
b: null,
c: {
d: 1
},
d: 0
}
console.log(oc(a, 'b')) // null
console.log(oc(a, 'b.c')) // undefined
console.log(oc(a, 'c.d')) // 1
console.log(oc(a, 'c.d.e')) // undefined
console.log(oc(a, 'd')) // 0