本文主要讲Gabriel Isenberg撰写的ES提案“Nullish coalescing for JavaScript”。 它提出?? 替换||的运算符,并提供默认值。这里先把这相提案叫作双问号操作符,如果你有好的叫法,欢迎留言讨论。
1. 概述
双问号 ?? 的操作符跟 || 类似,如果给定变量值为 null 或者 undefined,刚使用双问号后的默认值,否则使用该变量值。
如下:
1 | > undefined ?? 'default' |
2. 早期的 || 运算符号
直接来个例子来演示一下 || 运算,下面两个等式是等价的:
1 | a || b |
如果 a 是 truthy 值,则返回 a, 否则返回 b。
这使得使用||指定一个默认值成为可能,如果实际值是假的,那么将使用这个默认值:
1 | const result = actualValue || defaultValue; |
请注意,基本只有在实际值undefined或为null时才应使用默认值,这是有效的,因为undefined和null都是假(虚值)的:
1 | > undefined || 'default' |
遗憾的是,如果实际值是其他的虚值,也会使用默认值:
1 | > false || 'default' |
因此,这个getTitle()并不总能正常工作:
1 | assert.equal( |
3. 使用双问号操作符来解决 || 运算的问题
?? 主要是用来解决 || 操作符号的一些问题,以下两个表达式是等价的:
1 | a ?? b |
默认值是这样提供的:
1 | const result = actualValue ?? defaultValue; |
对于undefined和null, ??操作符的工作原理与||操作符相同
1 | > undefined ?? 'default' |
除了 undefined 和 null的其它虚值,?? 不会返回默认值。
1 | > false ?? 'default' |
使用 ?? 来重写 getTitle():
1 | function getTitle(fileDesc) { |
现在使用fileDesc调用它,它的.title是空字符串,仍然可以按符合咱们的预期工作:
1 | assert.equal( |
3.1 通过解构给定默认值
除了使用 ?? 给getTitle添加默认值,咱们也可以通过解构方式来给定默认值:
1 | function getTitle({title = '(Untitled)'}) { |
3.2 使用 ?? 操作符号的实际例子
作为一个现实的例子,咱们使用??来简化下面的函数。
1 | function countMatches(regex, str) { |
使用 ?? 操作符号后,简化如下:
1 | function countMatches(regex, str) { |
3.3 双问号(??)操作符与可选链(?)
双问号(??)的提出是为了补充可选链(?),来看看这两兄弟结合使用的场景(第A行):
1 | const persons = [ |
4. 兼容性
可以通过ECMAScript Next compatibility table 查看 ?? 支持情况。