前提
可选链,也就是
?.
与??
操作符,他实质上也是一种语法糖,通俗来讲就是 对象.属性1?.属性2??默认值,如果有对象的属性1,那么就继续读取属性2,如果没有则返回默认值。就就相当于一个三元运算符
他一般适用于嵌套对象的读取,链式的安全读取,详细可以参考 MDN,可以用于
- 对象
- 数组
- 函数
例子
const obj = {
a:1
}
我们如果直接读取对象中没有的属性,他就会直接报错
console.log(obj.b.c)
// Uncaught TypeError: Cannot read properties of undefined (reading 'c')
因为b不存在,所以读到b的时候返回的是undefined
我们把undefined
当做对象去读取那么就一定会报错
避免报错
通常我们避免报错,链式读取的时候一般都是用一下的方法去读取
const obj = {
a:1
}
console.log(obj.b && obj.b.c)
// undefined
如果想要是用更简洁的方法,可以使用可选链这个语法糖
console.log(obj.b?.c);
// undefined
默认值
通常读取不到我们都需要返回一个默认值
console.log(obj.b && obj.b.c || 0) // 如果没有值那么就返回0
// 0
当然我们也可以使用可选链进行操作
console.log(obj.b?.c??0) // 如果没有值那么就返回0
// 0
规范的使用可选链操作的时候,在
?.
运算符前面一般至少有一层读取(至少有一个.
),也就是对象.对象. ... 属性?.属性
,指定默认值的时候可以直接对象?.属性??默认值
数组与函数的使用
数组
数组的用法在这里也很简单,也就是
数组名?.[索引]
三点运算符在数组上面的时候还是挺少的
const arr = [2,3]
console.log(arr?.[1])
函数
const obj = {
a: 1,
};
console.log(obj.b?.())
// undefined
- 他的意思是b函数是否存在,如果存在则调用
- 但是如果你把存在的非函数属性当做函数去读取的话,那么他一定会报错
const obj = {
a: 1,
};
console.log(obj.a?.())
// obj?.a is not a function
- 这里意思可以理解为属性a是否存在,如果存在就调用,结果a并不是函数,所以会报错