# 如何优雅地链式取值

res.data.goods.list[0].price


if (res.data.goods.list[0] && res.data.goods.list[0].price) {
}


if (res && res.data && res.data.goods && res.data.goods.list && res.data.goods.list[0] && res.data.goods.list[0].price){
}


## 一、optional chaining

a?.b                          // undefined if a is null/undefined, a.b otherwise.
a == null ? undefined : a.b

a?.[x]                        // undefined if a is null/undefined, a[x] otherwise.
a == null ? undefined : a[x]

a?.b()                        // undefined if a is null/undefined
a == null ? undefined : a.b() // throws a TypeError if a.b is not a function
// otherwise, evaluates to a.b()

a?.()                        // undefined if a is null/undefined
a == null ? undefined : a()  // throws a TypeError if a is neither null/undefined, nor a function
// invokes the function a otherwise


## 二、通过函数解析字符串

var object = { a: [{ b: { c: 3 } }] };
var result = _.get(object, 'a[0].b.c', 1);
console.log(result);
// output: 3


function get (obj, props, def) {
if((obj == null) || obj == null || typeof props !== 'string') return def;
const temp = props.split('.');
const fieldArr = [].concat(temp);
temp.forEach((e, i) => {
if(/^(\w+)$(\w+)$$/.test(e)) { const matchs = e.match(/^(\w+)$(\w+)$$/);
const field1 = matchs[1];
const field2 = matchs[2];
const index = fieldArr.indexOf(e);
fieldArr.splice(index, 1, field1, field2);
}
})
return fieldArr.reduce((pre, cur) => {
const target = pre[cur] || def;

if(target instanceof Array) {
return [].concat(target);
}
if(target instanceof Object) {
return Object.assign({}, target)
}
return target;
}, obj)
}

var c = {a: {b : [1,2,3] }}
get(c ,'a.b')     // [1,2,3]
get(c, 'a.b[1]')  // 2
get(c, 'a.d', 12)  // 12


## 三、使用解构赋值

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

const {a: {c: {d: result2} = {}}} = c

## 四、使用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');  // default value

posted @ 2018-09-25 23:16  catgatp  阅读(543)  评论(0编辑  收藏  举报