JS深层取值的方法

前端取后端数据的时候, 经常会遇到一些比较深层的结构。比如
 

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

但是这样写, 就显得很繁琐, 而且不美观。 于是我们可以通过以下几种办法

1. Lodash的get方法
 

_.get(address, 'province.city.district.name')

2. 可选链操作符?. 目前主流的PC端浏览器均已支持
 

address?.province?.city?.district?.name

3. 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


4. 上面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'])
// => 邗江区


5. 巧用数组的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) 
// => 邗江区

6. 开源方法: 采用Github 上的一个名为 safe-touch 的库 , 链接: https://github.com/EnixCoda/safe-touch


本文的方法参考来源
1. 鱼头大佬的公众号: 鱼头的Web海洋的文章《你不知道的 Proxy:ES6 Proxy 可以做哪些有意思的事情?
2. [js对象如何优雅的取一个深度的值?](https://segmentfault.com/q/1010000016285893)文章中的评论

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值