ES2020新语法:可选链操作符 `?.`

项目中一个很常见的场景,从接口返回的数据,对象中的某个属性可能不存在,即 undefined ;或者尝试获取 DOM 元素,该元素不存在,即 null 。下面是 MDN 官方的例子,cat 属性可能不存在:

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

如果想要访问 catname 属性,像下面这样可能会报错:

const name = adventurer.cat.name

Uncaught TypeError: Cannot read property ‘name’ of undefined

如果 cat 属性不存在,那么 adventurer.cat 的值就是 undefined 。在 undefined 上访问 name 就会出现上面的报错信息。一旦报错,这段代码的执行就中断了,进而影响其他代码的执行甚至阻塞页面加载。

使用 AND 运算符

为了避免出现报错,项目中常见的作法是这样的:

const name = adventurer && adventurer.cat && adventurer.cat.name

AND运算符 && 当左边的表达式为 true ,不管右边表达真假,都返回右边的表达式;当左边表达式为 false 直接返回左边的表达式

上面的代码中,查找一个深度嵌套的子属性时,需要验证之间的引用。这样当 cat 属性不存在时,提前进行了返回,从而避免报错。

这样做很明显有个缺点,当访问的属性嵌套了很多层,校验的语句会变得很长,影响代码可读性。

使用可选链操作符

可选链操作符(?.),在访问子属性之前,不再需要明确地校验当前属性的状态,再并用短路计算获取最终结果:

const name = adventurer?.cat?.name

通过使用 ?. 操作符取代 . 操作符,JavaScript 会在尝试访问 adventurer.cat.name 之前,先隐式地检查并确定 adventurer.cat 既不是 null 也不是 undefined 。如果 adventurer.catnull 或者 undefined ,表达式将会短路计算直接返回 undefined

这等价于以下表达式,但实际上没有创建临时变量:

let temp = adventurer.cat;
let name = ((temp === null || temp === undefined) ? undefined : temp.name);

可选链常用语法如下:

obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)

函数调用

函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常:

let result = someInterface.customMethod?.();

对象属性

可选链用于访问对象属性:

let nestedProp = obj?.first;

对象属性支持表达式:

let nestedProp = obj?.['prop' + 'Name'];

可选链不能用于赋值

注意:可选链只能用于访问属性,不能用来赋值。

let object = {};
object?.property = 1;

上面这段代码执行会报错:

Uncaught SyntaxError: Invalid left-hand side in assignment

数组元素

let arrayItem = arr?.[42];

短路计算

当在表达式中使用可选链时,如果左操作数是 null 或 undefined,表达式将不会被计算:

let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
// 相当于下面代码
// let prop = potentiallyNullObj && x++;

console.log(x); // x 将不会被递增,依旧输出 0

连用可选链操作符

可以连续使用可选链读取多层嵌套结构:

let customerCity = customer.details?.address?.city;
let duration = vacations.trip?.getTime?.();

参考:
可选链操作符 - MDN

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值