目录
一、前言
二、案例
三、方法一:AND运算符
四、方法二:可选链操作符( ?. )
1. 语法
2. 可选链与函数调用
3. 处理可选的回调函数或事件处理器
4.可选链和表达式
5.可选链访问数组元素
6.使用空值合并操作符
一、前言
今天看一个实习生写的代码,Po一个截图:
我是个菜鸡,我是真的没有【item?.Name】这么用过,我也不知道是啥意思。
然后查了一下,叫做: 可选链操作符 ( ?. ) 。
二、案例
项目中一个很常见的场景,从接口返回的数据,对象中的某个属性可能不存在,即
undefined
;或者尝试获取 DOM 元素,该元素不存在,即null
。
下面是 MDN 官方的例子,cat
属性可能不存在:
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};
如果想要访问 cat
的 name
属性,像下面这样可能会报错:
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
直接返回左边的表达式。
缺点:
当访问的属性嵌套了很多层,校验的语句会变得很长,影响代码可读性。
四、方法二:可选链操作符( ?. )
可选链操作符( ?. ) 允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空 ( null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。
当尝试访问可能不存在的对象属性时,可选操作符将会使表达式更短、更简明。在去访问一个对象的内容时,如果不能确定哪些属性存在时,可行链操作符是很有帮助的。
const myInfo = {
name: '007',
like: 'novel',
}
// 使用可选链进行获得对象属性
console.log(myInfo.school?.name) // 输出undefined
// 使用可选链进行函数调用
console.log(myInfo.action?.read()) // 输出undefined
1. 语法
obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)
2. 可选链与函数调用
当尝试调用一个可能不存在的方法时也可以使用可选链。这将是很有帮助的,比如,当使用一个API的方法可能不可用时,要么因为实现的版本问题,要么因为当前用户的设备不支持该功能。
函数使用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。
let result = someInterface.customMethod?.();
3. 处理可选的回调函数或事件处理器
如果通过解构获得一个对象的回调函数或fetch方法,你可能得到不存在的值,从而不能当做函数直接调用,除非你已经校验了他们的存在性。使用?.的你可以忽略这些额外的校验:
// 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也不会有异常
}
}
4.可选链和表达式
当使用方括号与属性名的形式来访问属性时,你也可以使用可选链操作符:
let nestedProp = obj?.['prop' + 'Name'];
5.可选链访问数组元素
let nestedProp = obj?.['prop' + 'Name'];
6.使用空值合并操作符
空值合并操作符可以在使用可选链时设置一个默认值:
let myInfo = {
name: '007',
};
let mySex = myInfo?.sex ?? 'man';
console.log(mySex); // man
这里的 ?? 是 Nullish Coalescing 运算符,它的作用是在左侧的表达式值为 null 或 undefined 时,返回右侧的默认值。在这个例子中,如果 myInfo?.sex 的值为 null 或 undefined,则 mySex 的值将被设置为 'man'。如果 myInfo?.sex 的值不为 null 或 undefined,则 mySex 的值将被设置为 myInfo?.sex 的值。