TS 3.7 新增的超甜“语法糖”:Optional Chaining & Nullish coalescing operator

Posted by Lxxyx on 2019-09-30

前言

如果说近期我最关注的的事情,那么无疑是 TS 3.7 的更新。因为在官方的迭代计划中,其包含了众多令人期待的新功能。

其中在 TS 语言层面的更新令我尤为激动(具体的改动可以看下面的链接)

而今天我想介绍的,就是 TS 3.7 中个人认为最甜的语法糖:“Optional Chaining & Nullish coalescing operator”

image.png

Optional Chaining

这个 Feature 于我而言,是相当有用的特性。

因为我相信,大部分的开发者都和我一样,为了保证能正确的取到值与代码不报错。写过这样的代码:

1
2
const res = getData();
const videoCover = res && res.data[0] && res.data[0].video && res.data[0].video.cover;

虽然可以通过一些类似于 lodash.get/ts-optchain 的工具去解决这个问题,但总归是需要考虑包体积与兼容性的问题。

而且这个 Feature,其实已经在 C#/Swift/Kotllin/… 等主流语言存在多时,属于常见功能。
于是就有人在 TC 39 发起了 proposal-optional-chaining 的提案,时至今日已经是处于 Stage 3 状态,即将合并进入 ECMAScript。

Syntax

这个语法糖可以说是相当简洁易懂了,如下面的代码所示。

1
2
3
obj?.prop; // optional static property access
obj?.[expr]; // optional dynamic property access
func?.(...args); // optional function or method call

你可以通过 ?. 的操作符,实现可选链式调用,其中包括以下功能:

  • 读取属性
  • 读取动态属性
  • 执行函数

基本上 Cover 到了我们日常使用的情况。

Demo

举个 🌰,可以看下面的获取属性 Demo,不难看出获取属性从此可以变得非常简洁:

1
2
3
4
5
let nestedProp = obj.first && obj.first.second;

// ===>

let nestedProp = obj.first?.second;

通过使用?.操作符取代.操作符。JavaScript 知道在尝试访问obj.first.second之前先明确的校验并确定obj.firstt 是非null且非undefined。如果obj.firstnullundefined,表达式将会短路计算直接返回undefined

MDN - Optional Chaining



Nullish coalescing operator

另一个值得关注的 Feature 是 Nullish Coalescing,同样也是进入了 stage 3。

这是与 proposal-optional-chaining 十分搭配的 feature,通过 ?? 来表示默认值的功能。(感觉后续会看见 JS 中遍地都是 ?????? 的场景。。)

Nullish coalescing 的用法和 JS 的默认值语法:“||”非常像,但还是有一些本质的不同。

“||” 语法在进行判断时,实际上是基于 JS 的 Truthy 特性去判断的。隐式类型转换带来的问题,代表着在 “0 || 1 ”之类的场景下,实际上可能是不符合用户期望的。

而 “??” 的判断条件则更为严谨,我们称之为 nullish。nullish 实际上指的是这个值与 null/undefined 严格相等,因此与 Optional Chaining 可以说是相当搭配了。

Demo

举个 🌰,可以通过下面的示例了解这个 feature。

1
2
3
4
5
6
false ?? true; // => false
0 ?? 1; // => 0
'' ?? 'default'; // => ''

null ?? []; // => []
undefined ?? []; // => []

真甜

上面两个 feature 总结下来,非常符合语法糖的特性:“使用简单,用户友好”。

而同时在 TC39 的 Proposals 中,我们可以看到许多类似的提案正在不断的被提出,不断的在简化着我们的编码:

不得不说,虽然语法糖有一定的学习成本,但是:

image.png