可选链(?.)

可选链 “?.

可选链 ?. 是一种访问嵌套对象属性的安全的方式。即使中间的属性不存在,也不会出现错误。
类似于.链式访问,但是链式访问在中间某个属性不存在时,会报错。

语法和解析

obj?.prop  // 如果 obj 存在则返回 obj.prop,否则返回 undefined。
// 等同于
obj  == null || obj == undefined ? undefined : obj.prop

obj?.[prop]  // 如果 obj 存在则返回 obj[prop],否则返回 undefined。
// 等同于
obj  == null || obj == undefined ? undefined : obj[prop]

obj?.method()  // 验证obj存在则执行method(),否则返回undefined
// 等同于
obj  == null || obj == undefined ? undefined : obj.method()

obj.method?.()  // 如果 obj.method 存在则调用 obj.method(),否则返回 undefined。
// 等同于:obj对象必须存在,method()可选
typeof obj.method == "function" ? obj.method() ? undefined

在这里插入图片描述

访问“不存在属性”

如果某个属性不存在:

let user = null
let name = user.name // 报错 Uncaught TypeError: Cannot read properties of null (reading 'name')

因为 usernull,尝试读取 user.name 会失败,并收到一个错误。
但是在实际应用场景中,我们可能希望返回的值是undefined
为了避免报错,我们需要明确校验user

let user = null
let name1 = user ? user.name : undefined // undefined 
let name2 = user && user.name;  // undefined

使用可选链?.,不需要明确校验user

let user = null
let name = user?.name // undefined 
let street = user?.address?.street // undefined

使用可选链?.,JavaScript 会在尝试访问 user.name 之前,先隐式地检查并确定 user 是否存在(user是不是null/undefined)。

解析user?.name

  • user 存在(既不是null,也不是undefined),则结果与 user.name 相同,
  • user 不存在(当 userundefined/null 时),则返回 undefined

请注意:?. 语法使其前面的值成为可选值,但不会对其后面的起作用。

例如,在 user?.address.street 中,?. 允许 usernull/undefined(在这种情况下会返回 undefined)也不会报错,但这仅对于 user

user后面的属性是通过常规方式.访问的。如果address属性为 null/undefined,会立即报错。

如果希望不报错,那要让每个属性都是可选的,即使用 ?. 来替换 .user?.address?.street?.允许user,address,streetnull/undefined

可选链?.[]访问属性

let user = {
	name: "zhang",
	"like music": true
}
alert( user?.name); // zhang
alert( user?.["like music"] )  // true

可选链?.()访问对象的方法

let user = {
	sayBaiBai: "baibai",
	sayHi() {
		alert("hello")
	}
}
user.sayHi?.(); // hello
user.sayYes?.(); // undefined, 啥都没发生(没有这样的方法)
user.sayBaibai?.(); // undefined, 啥都没发生(没有这样的方法)

可选链?.访问数组

let arr = [1, 3, 5]
alert( arr?.[0] ); // 1

可选链 ?.前的变量必须已声明

// ReferenceError: user is not defined
user?.name; // 报错,未声明变量 user

可选链 ?. 不能用于赋值

let user = null
user?.name = "Zhang" // Error,不起作用
// 因为它在计算的是:undefined = "Zhang"

let admin = {}
admin?.name = "zhang" // Error
// Uncaught SyntaxError: Invalid left-hand side in assignment

?.导致短路效应

当在表达式中使用可选链时,如果 ?. 左边部分是 nullundefined,就会立即停止运算(“短路效应”)。
因此,如果在 ?. 的右侧有任何进一步的函数调用或操作,它们均不会执行。

let user = null;
let x = 0;
// 读取user.key1
user?.[key`${x++}`]; // 没有 "user",因此代码执行没有到达 sayHi 调用和 x++

alert(x); // 0,值没有增加

连续使用可选链

let user = {
	name: "zhang",
	details: {
		likes: {
			music: true
		}
	}
}
let isLikeMusic = user?.details?.likes?.music // true
let english = user?.details?.likes?.english // undefined

总结

可选链?. 检查左边部分是否为 null/undefined,如果不是则继续运算,否则立即停止运算。
可选链 ?.前的变量必须已声明。
可选链 ?. 不能用于赋值。

可选链?. 链使我们能够安全地访问嵌套属性。

根据代码逻辑,仅在当左侧部分不存在也可接受的情况下,谨慎地使用 ?.。滥用 ?.,会导致代码中的错误在不应该被消除的地方消除了,增加调试难度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值