JS 特性:可选链(?.)
什么是可选链
可选链操作符( ?. )是一个新的js api,允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。
语法:
obj?.prop obj?.[expr] func?.(args)
上述是官方描述,举个例子对象嵌套了好多层,需要获得对象深层的值得时候,这就意味着你需要写很长的属性访问,如下:
const person = { details: { name: { newName: "aa", oldName: "aa", } age: "18", }, jobs: [ "H5", "Java" ] } const personNewName = person.details.name.newName;
上面的代码如果我的person.details.name等任何一层数据有问题或者不存在的时候,js就会报错,我们一般会这么改进:
const personNewName = person && person.details && person.details.name person.details.name.newName|| '';
可以看到为了访问某个人的 newName,代码变得非常不优雅,会有多个&&代码量也很大。可选链 就是为了解决这个问题而诞生的。
用法
有了可选链操作符(?.),在访问 person.details.name.newName 之前,不再需要明确地校验 person.details.name 的状态,再并用短路计算获取最终结果:
const personFirstName = person?.details?.name?.firstName;
其实就是在属性访问符 . 的前面加了个问号。我们看上面语句中第一个 ?. ,从 JS 层面,它表示如果 person 的值为 null 或者 undefined,就不会报错而返回 undefined,否则才继续访问后面的 details 属性。而如果后面的属性访问链中有任何一个属性为 null 或者 undefined,那么最终的值就为 undefined。
这等价于以下表达式,但实际上没有创建临时变量:
let temp = person.details; let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.name); let temp1 = person.details.name; let nestedProp = ((temp1 === null || temp1 === undefined) ? undefined : temp1.firstName);
可选链与函数调用
函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。
let result = someInterface.customMethod?.();
注意: 如果存在一个属性名且不是函数, 使用 ?. 仍然会产生一个 TypeError 异常 (x.y is not a function).
注意: 如果 someInterface 自身是 null 或者 undefined ,异常 TypeError 仍会被抛出 someInterface is null 如果你希望允许 someInterface 也为 null 或者 undefined ,那么你需要像这样写 someInterface?.customMethod?.()
可选链和表达式当使用方括号与属性名的形式来访问属性时,你也可以使用可选链操作符:
let nestedProp = obj?.['prop' + 'Name'];
可选链不能用于赋值
let object = {}; object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
可选链访问数组元素
let arrayItem = arr?.[42];
规范