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
下面这个错误在 JavaScript 中最为常见
unable to get property of undefined or null reference
通常为了解决这个问题,我们可以使用
&&
操作符来取对象属性值。不过当数据很长的时候就特别麻烦,ECMA2020 通过了一项提案Optional Chaining,用语法糖的形式解决了这个问题:
当 user 为 null 或者 undefined 的时候直接返回,而不继续往后取值。
除了取属性外,还支持取索引、取方法、当做函数运行。
不过需要注意的是,以下场景并支持
目前可以在 TypeScript3.7 以及 Chrome 80 canary 中使用。
有些时候我们需要给属性赋于默认值,如下所示,height 属性的默认值为 400。
但是在 js 下这样做是不对的,因为如果 height 值为 0,那么也因为 0 隐式转化为布尔值是 false 而取值 400,这个不是我们想要的结果。
我们这样改:
这样当 height 值为 undefined 或者 null 都可以得到想要的结果,这里使用 null 和 undefined 在非严格等于下互等,而不和其他值相等的特性。但是这个会被大部分 linter 报错,如果使用严格等于的话,又会特别长:
新的提案 Nullish Coalescing 解决了个问题:
目前也是可在 TypeScript3.7 或 Chrome Cannay 80 中使用。