
?
的新提案。
Optional chaining
optional chaining
可以被直译为「可选链式取值」,有四种语法结构:
- 对象静态属性:
obj?.prop
- 对象动态属性:
obj?.[exp]
- 数组索引:
arr?.[index]
- 函数调用:
func?.(args)
这些语法大同小异(后面的三种写法的 .
不要忘了哦),本质都是帮助我们减少一些判断值是否是 null
或者 undefined
的条件语句的书写。这样面对一个对象,原本的安全取值方式:
console.log(obj !== null && obj !== undefined ? obj.prop : undefined)
就可以简化为
console.log(obj?.prop);
且逻辑完全等价。
无需更多的例子,相信大家已经基本学会这种语法。下面罗列了一些 optional chaining
容易被忽略的语法细节:
- 返回
undefined
:无论?
前的值是null
还是undefined
,表达式都会返回undefined
,即没有办法通过它来区分两者:
null?.someProp === undefined // true
- 不做函数检查:进行函数可选调用时,这种语法并不会帮你检查是不是函数,而仅仅是检查是否是
null
或者undefined
,因而直接调用一个不是函数的值仍会报错:
1?.(); // TypeError: 1 is not a function
- 短路:同逻辑符
||
和&&
一样,这种新语法在?
前遇到null
或undefined
之后便会产生短路,不再执行后续的表达式,直接返回undefined
:
const getPropName = () => {
console.log('executed');
return 'a';
};
null?.[getPropName()];
// 控台没有输出 'a'
Nullish coalescing operator
Nullish coalescing operator 可直译为「空位合并运算符」,语法形式为 exp1 ?? exp2
是一个有点类似 ||
的合并符,它仅会在 exp1
的值为 null
或 undefined
时计算并返回 exp2
的值:
例如我们需要在界面上展示一个数值,在数值不存在的时候展示 '--',应该怎么写呢?value || '--'
是不行的,因为在 value
等于 0
时也展示了 '--'
,而 0
显然是合法的数值。这时使用 value ?? '--'
就会很合适。
更多例子:
false ?? true // false
0 ?? '--' // 0
null ?? '--' // '--'
下面是一些语法细节:
- 短路:同
||
和&&
一样,??
在没有碰到空值的情况下不会执行后面的表达式
const foo = () => console.log('executed');
1 ?? foo();
// 控台没有输出 'executed'
- 混用报错:
??
禁止与||
或&&
直接混用,会造成语法错误!不过可以通过括号来将他们「隔开」
null || undefined ?? 'foo'; // SyntaxError: Unexpected token '??'
true && false ?? 'foo'; // SyntaxError: Unexpected token '??'
(null || undefined) ?? 'foo'; // 'foo'
true && (false ?? 'foo'); // 'foo'
浏览器支持
作为草案,这两个带问号的语法糖的浏览器支持并不好,五大浏览器的最新版都还有一半没有支持它们,nodeJS 对这两项特性目前还都不支持。
但在更为实际实际的开发层面,babel 已经为他们出了转码插件:
- @babel/plugin-proposal-optional-chaining
- @babel/plugin-proposal-nullish-coalescing-operator
Typescript 也从 3.7 开始支持这两个特性。
所以只要使用合理的转码工具,还是可以通过它们来简化我们的源码的。