什么问题

安全取值是为了避免在代码运行过程中,某些数据错误导致应用发生异常的情况。

image.png

例如存在一个对象。

  1. let obj = {
  2. person: {
  3. name: '小明',
  4. }
  5. }

如果我们直接取值。

  1. let name = obj.person.name

如果obj为null或者undefine,又或者obj.person也出现这样的问题。
整个应用就会发生异常影响正常使用。

旧有的方案

在语言层面没有很好地支持之前,为了安全取值,我们一般有两种方案。

  1. 利用&&运算符

    1. let name = obj && obj.person && obj.person.name
  2. 利用函数 ```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’)

  1. 两种方案都有缺点:第一种代码太长,对象嵌套越深,代码就会越长;第二种需要增加额外的函数。
  2. <a name="eto7s"></a>
  3. ### 新方案
  4. 最佳的方案,莫过于语言层的支持了。<br />ES11增加了一个新特性:可选链。<br />以上的安全取值会变成这样的写法。
  5. ```javascript
  6. let name = obj?.person?.name

这样的写法等价于。

  1. let name = obj && obj.person && obj.person.name

好了,这样的解决方法简直完美。

等等,还剩下一个问题,这个语法的支持度如何?

image.png
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining