前端取后端数据的时候, 经常会遇到一些比较深层的结构。比如
const address = {
province: {
name: '江苏省',
city: {
name: '扬州市'
district: {
name: '邗江区'
}
}
}
}
这时候如果我们要取最里面区域的名字时候, 最简单的写法就是:let district = address.province.city.district.name
, 如果后台返回的是正常的数据的还好, 如果遇到其中有null或者结构不全的, 很容易就会报'xxx undefined'的js错误, 如果项目再是要求TS强类型检查的, 可能连编译都不能通过, 就很头疼。
为了避免这个问题, 我们可能硬着头皮这么写: let district =address && address.province && address.province.city && address.province.city.district && address.province.city.district.name
但是这样写, 就显得很繁琐, 而且不美观。 于是我们可以通过以下几种办法
- Lodash的get方法
_.get(address, 'province.city.district.name')
- 可选链操作符?. 目前主流的PC端浏览器均已支持
address?.province?.city?.district?.name
- Proxy代理监听
/**
* @param target
* @param exec 取值属性
* @returns {*}
*/
function getter(target, exec = '_') {
return new Proxy({}, {
get: (o, n) => {
return n === exec ?
target :
getter(typeof target === 'undefined' ? target : target[n], exec)
}
});
}
getter(address).province.city.district.name._ // 邗江区
getter(address).province.city.district.name1._ // undefined
- 上面Proxy的ES5写法
function getter(obj, arr) {
return arr.length === 0 ? obj : getter(typeof obj === 'undefined' ? undefined : obj[arr[0]], arr.slice(1))
}
getter(address, ['province', 'city', 'district', 'name'])
// => 邗江区
- 巧用数组的reduce方法
function getIn(p, o) {
return p.reduce(function(xs, x) {
return (xs && xs[x]) ? xs[x] : null;
}, o);
}
getIn(['province', 'city', 'district', 'name'], address)
// => 邗江区
本文的方法参考来源
- 鱼头大佬的公众号: 鱼头的Web海洋的文章《你不知道的 Proxy:ES6 Proxy 可以做哪些有意思的事情?
- js对象如何优雅的取一个深度的值?文章中的评论
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。