链式取值(转载整理)
链式取值(转载整理)
Lieme实际开发的过程中,遇到取某个对象下的某个值,或者是未知对象下的某个属性的值。如果不确定这个值有没有怎么办?
res.data.money.list[0].price
比如上面这种,想获取data下面list数组的第一个的price的值。如果我们直接这样写,在money下没有list的时候就会报Uncaught TypeError: Cannot read property ‘list’ of undefined。之前是这样处理的。
if (res.data.money.list[0] && res.data.money.list[0].price) {
    // 实际业务逻辑部分
}
或者是更全的
if (
    res && 
    res.data && 
    res.data.money && 
    res.data.money.list && 
    res.data.money.list[0] && 
    res.data.money.list[0].price) {
    // 实际业务逻辑部分
}
可以看多如果层级更深这样写起来不是很优雅,所有就有了下面的方法。
1、通过babel插件 babel-plugin-transform-optional-chaining 来实现
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()  
2、通过函数解析字符串
// lodash的_.get方法
var object = { a: [{ b: { c: 3 } }] };
var result = _.get(object, 'a[0].b.c', 1);
3、使用解构赋值
const c = {a:{b: [1,2,3,4]}}
const { a: result } = c;
// result : {b: [1,2,3,4]}
cosnt {a: { c: result = 12 }} = c
// result: 12
4、使用Proxy
function pointer(obj, path = []) {
    return new Proxy({}, {
        get (target, property) {
            return pointer(obj, path.concat(property))
        },
        apply (target, self, args) {
            let val = obj;
            let parent;
            for(let i = 0; i < path.length; i++) {
                if(val === null '' val === undefined) break;
                parent = val;
                val = val[path[i]]    
            }
            if(val === null '' val === undefined) {
                val = args[0]
            }
            return val;
        }
    })
}
使用:
let c = {a: {b: [1, ,2 ,3]}}
pointer(c).a();   // {b: [1,2,3]}
pointer(c).a.b(); // [1,2,3]
pointer(d).a.b.d('default value');  




