可选链 ?.
?.即是可选链(Option Chaining)操作符。可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。
const val = a?.b
上述的代码会自动检查对象 a 是否为 null 或 undefined,如果是的话就立即返回 undefined,这样就可以立即停止某些表达式的运行。你可能已经想到可以使用 ?. 来替代很多使用 && 执行空检查的代码
if(a && a.b) { }
if(a?.b){ }
/**
* if(a?.b){ } 编译后的ES5代码
*
* if(
* a === null || a === void 0
* ? void 0 : a.b) {
* }
*/
但需要注意的是,?. 与 && 运算符行为略有不同,&& 专门用于检测 falsy 值,比如空字符串、0、NaN、null 和 false 等。而 ?. 只会验证对象是否为 null 或 undefined,对于 0 或空字符串来说,并不会出现 “短路”。
注意
- 函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回
undefined而不是抛出一个异常。
let result = someInterface.customMethod?.();
注意:如果存在你一个属性名而不是函数,使用
?.仍然会产生TypeError异常,例如(someInterface.customMethod is not a function)
- 可选链不能用于赋值
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
- 使用空值合并操作符可以设置一个默认值
let customer = {
name: "Carl",
details: { age: 82 }
};
let customerCity = customer?.city ?? "暗之城";
console.log(customerCity); // “暗之城”
空值合并 ??
空值合并操作符( ?? )是一个逻辑操作符,当左侧的操作数为null或undefined时,返回其右侧操作数,否则返回左侧操作数。
与逻辑或操作符(||)不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,'' 或 0)时。见下面的例子。
注意
- 与
AND或OR操作符共用时需要规定优先级 因为空值合并操作符和其他逻辑操作符之间的运算优先级/运算顺序是未定义的)这种情况下会抛出SyntaxError。
null || undefined ?? "foo"; // 抛出 SyntaxError
true || undefined ?? "foo"; // 抛出 SyntaxError
(null || undefined) ?? "foo"; // 返回 "foo"
逻辑空赋值 ??=
逻辑空赋值运算符 (x ??= y) 仅在 x 是 null 或 undefined 时对其赋值。
const a = { duration: 50 };
a.duration ??= 10;
console.log(a.duration);
// expected output: 50
a.speed ??= 25;
console.log(a.speed);
// expected output: 25
指数赋值 **=
let a = 3;
console.log(a **= 2);
// expected output: 9
console.log(a **= 0);
// expected output: 1
console.log(a **= 'hello');
// expected output: NaN