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

3 篇文章 0 订阅
本文探讨了在JavaScript项目中如何使用可选链操作符(?.)优雅地处理对象属性可能存在undefined或null的情况,提高代码健壮性和可读性。通过实例和语法解析,介绍了如何避免属性访问时的报错,并关注其在深度嵌套和函数调用中的应用。
摘要由CSDN通过智能技术生成

项目中一个很常见的场景,从接口返回的数据,对象中的某个属性可能不存在,即 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.cat 是 null 或者 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 arr=[23,45,4,56]
console.log(arr?.[1])//45
console.log(arr?.[4])//undefined

短路计算

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

let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
// 相当于下面代码
// let prop = potentiallyNullObj && x++;
console.log(x); //0 (x 将不会被递增,依旧输出 0)
console.log(prop); //undefined
console.log(potentiallyNullObj ); //null

注意:prop没有被赋值 

连用可选链操作符

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值