这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
可选链操作符(?.)
允许读取位于连接对象链深处的属性的值,而不必明确链中的每个引用是否有效。可选链操作符可以连用。
?.操作符类似.链式操作符,不同之处在于如果引用为null或undefined链式操作符会直接报错,但可选链操作符不会报错,直接返回undefined。
当对象属性可能不存在时,需要使用可选链操作符,比如在react渲染dom的时候,我们可能还没有获取到接口中的数据,渲染视图的时候,我们就可以使用可选链操作符。
语法
obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)
举个栗子
const obj = {
a: 1,
name: 'text'
c: null,
d: undefined
}
console.log(obj.b?.name) // undefined
console.log(obj.b.name) // "TypeError: Cannot read properties of undefined (reading 'name')
console.log(obj.c?.name) // undefined
console.log(obj.d?.name) // undefined
同样也可以使用于函数调用,比如中我工作中经常用的swiper的slide函数,如果在useEffect中使用,会出现dom加载还没有完成slide函数就执行的问题,我们就可以在slide已经绑定在实例时再执行。
mySwiper.slide?.()
// 等价于
(mySwiper.slide === null || mySwiper.slide === undefined) ? undefined : mySwiper.slide()
如果slide本身不是一个函数则还是会报错slide is not a function
如果没有可选链操作符,我们往往采取这样的方式避免报错。但是如果对象嵌套的层级很深,表达式就会太长。
obj.b && obj.b.name
obj.b && obj.b.name && obj.b.name.first
使用可选链表达式会在访问属性时,隐式的判断可选链前的表达式不为null或者undefined,如果是则会返回undefined。
可选链操作符是短路计算,比如obj为null,后面的就不会执行。
let obj = null
let a = 1
let b = obj?.[a++]
console.log(a) // 1
不可用作赋值
let obj = {}
let a = obj?.name = 'a'
console.log(a) // "SyntaxError: Invalid left-hand side in assignment
空值合并操作符(??)
空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数。和可选链操作符一致左边不为null或undefined右边不执行
空值合并操作符可以和可选链操作符一起使用,在返回undefined时,给一个默认值。 很多可能会有疑问,使用逻辑或操作符不是效果一样吗。
逻辑或操作符会在左侧为假值时返回右侧值,如果使用||设置默认值,''和0都是假值也会返回默认值。
const obj = {
name: 'text'
}
let a = obj.a?.b ?? '默认值'
console.log(a) // 默认值
const a = 0 ?? 1
const b = 0 || 1
console.log(a) // 0
console.log(b) // 1
可以用作赋值
let obj = {}
let a = obj?.name ?? '默认值'
console.log(a) // 默认值
??不可直接与||和&&使用,因为它们的优先级没有明确的定义,如果通过()增加优先级即可使用。
null || undefined ?? "foo"; // 抛出 SyntaxError
(null || undefined ) ?? "foo"; // 返回 "foo"
逻辑或(||)
当且仅当其中一个或多个操作数为真时为真。它通常与布尔值一起使用返回一个布尔值。如果和非布尔值一起使用,则返回非布尔值。
在第一个值执行为真时返回第一个,否则返回第二个值。 null、NaN、undefined、''、0都可以转换为false
function A(){ console.log('called A'); return false; }
function B(){ console.log('called B'); return true; }
console.log( A() || B() );
// "called A" "called B" true
console.log( B() || A() );
// "called B" true
a = 'Cat' || 'Dog' // "Cat"
b = false || varObject // varObject
逻辑与(&&)
&& 优先级高于 ||
当且仅当所以操作数为真时为真。它通常与布尔值一起使用返回一个布尔值。如果和非布尔值一起使用,则返回非布尔值。
在第一个值执行为真时返回第二个,否则返回第一个值。
function A(){ console.log('called A'); return false; }
function B(){ console.log('called B'); return true; }
console.log( A() && B() ); // called A false
console.log( B() && A() );
// called B called A false
a = 'Cat' && 'Dog' // "Dog"
b = false && varObject // false