什么问题
安全取值是为了避免在代码运行过程中,某些数据错误导致应用发生异常的情况。
例如存在一个对象。
let obj = {
person: {
name: '小明',
}
}
如果我们直接取值。
let name = obj.person.name
如果obj为null或者undefine,又或者obj.person也出现这样的问题。
整个应用就会发生异常影响正常使用。
旧有的方案
在语言层面没有很好地支持之前,为了安全取值,我们一般有两种方案。
利用&&运算符
let name = obj && obj.person && obj.person.name
利用函数 ```javascript function getAttribute(obj, key) { let c = deepClone(obj); // 深度复制代码省略… let dataPath = key.split(‘.’); for (let k of dataPath) { c = c[k]; } return c; }
let name = getAttribute(obj, ‘person.name’)
两种方案都有缺点:第一种代码太长,对象嵌套越深,代码就会越长;第二种需要增加额外的函数。
<a name="eto7s"></a>
### 新方案
最佳的方案,莫过于语言层的支持了。<br />ES11增加了一个新特性:可选链。<br />以上的安全取值会变成这样的写法。
```javascript
let name = obj?.person?.name
这样的写法等价于。
let name = obj && obj.person && obj.person.name
好了,这样的解决方法简直完美。
等等,还剩下一个问题,这个语法的支持度如何?
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining