可选链操作符
?.
允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
此方法不兼容IE浏览器
一、语法
obj?.prop // 对象属性是否存在
obj?.[expr] // 同上
arr?.[index] // 数组元素是否存在
func?.(...args) // 函数或对象方法是否存在
二、基本用法
1. 查找一个深度嵌套的可能不存在的子属性时
let nestedProp = obj.first && obj.first.second;
// 代替
let nestedProp = obj.first?.second;
通过使用?.
操作符取代 . 操作符,JavaScript 会在尝试访问 obj.first.second
之前,先隐式地检查并确定 obj.first
既不是 null
也不是 undefined
。如果obj.first
是 null
或者 undefined
,表达式将会短路计算直接返回 undefined
2. 调用一个可能不存在的方法
函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。
let result = someInterface.customMethod?.();
备注:如果存在一个属性名且不是函数, 使用 ?. 仍然会产生一个 TypeError 异常 (x.y is not a function).
备注:如果 someInterface 自身是 null 或者 undefined ,异常 TypeError 仍会被抛出 someInterface is null 如果你希望允许 someInterface 也为 null 或者 undefined ,那么你需要像这样写
someInterface?.customMethod?.()
处理可选的回调函数或者事件处理器
// ES2019的写法
function doSomething(onContent, onError) {
try {
// ... do something with the data
}
catch (err) {
if (onError) { // 校验onError是否真的存在
onError(err.message);
}
}
}
// 使用可选链进行函数调用
function doSomething(onContent, onError) {
try {
// ... do something with the data
}
catch (err) {
onError?.(err.message); // 如果onError是undefined也不会有异常
}
}
3. 可选链不能用于赋值
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
4. 可选链和表达式
当使用方括号与属性名的形式来访问属性时,你也可以使用可选链操作符
let nestedProp = obj?.['prop' + 'Name'];
当在表达式中使用可选链时,如果左操作数是 null 或 undefined,表达式将不会被计算,例如
let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
console.log(x); // x 将不会被递增,依旧输出 0
5. 可选链访问数组元素
let arrayItem = arr?.[42];
6. 使用空值合并操作符设置默认值
空值合并操作符
可以在使用可选链时设置一个默认值:
let customer = {
name: "Carl",
details: { age: 82 }
};
let customerCity = customer?.city ?? "暗之城";
console.log(customerCity); // “暗之城”