js中的 ? 操作符
三目运算符 ?
let z = 0, x = 10, y = 20;
// if 逻辑判断
if (x > y) {
z = 30
} else {
z = 30
}
// 三目运算简化 if
z = x > y ? 20 : 30
非常简单也非常的常见,如果你还不知道,该赶紧补习一下啦;
可选链操作符 ?.
let obj = { name: '掘进好友', age: 30 }
console.log('昵称', obj.nickName.toString())
当我们在执行上面的代码时,因为obj
对象上并不存在nickName
属性,所以当读取obj.nickName
时,得到的将会是 undefined
,而undefined
是没有toString()
方法的,所以这个时候程序就会报错了。
以前我们的解决方案是加一层判断,确保访问的对象不为undefined
或者 null
,我们才做后续操作,具体代码如下:
let obj = { name: '掘进好友', age: 30 }
if(obj.nickName){
console.log('昵称', obj.nickName.toString())
}
这样写代码虽然解决了问题,但是写起来太繁琐,不够优雅,所以新版 JS 增加了可选链操作符来简化这一过程。上面的代码用可选链操作符简化如下
let obj = { name: '掘进好友', age: 30 }
console.log('昵称', obj.nickName?.toString())
所以?.
可选链操作符的作用就是,如果obj
对象的nickName
属性值不为null
或 undefined
则调用其toString()
方法,如果不存在则不调用,实际效果与if
判断是等价的。
可选链操作符在深层嵌套时,优势就更明显了,简便的不是一点半点,举个例子,看如下代码:
let demo = {
setp1: {
name: '步骤一',
step2: {
name: '步骤二'
}
}
}
// 如果我们想访问【步骤二】的 name 属性,即
demo.step1.step2.name
// 我们为了确保安全性,过去我们可能要写如下代码
if (demo && demo.step1 && demo.step1.step2 && demo.step1.step2.name) {
demo.step1.step2.name.toString()
}
// 用可选链的话
demo?.step1?.step2?.name?.toString()
空值合并操作符 ??
这是一个逻辑操作符,与||
操作符十分相似,但是它们并不是等价的,具体的区别如下:
let a = 0
let b = ''
let c = null
let d = undefined
let x = a ?? 100 // x 等于 0
let y = b ?? 100 // y 等于 ''
let z = c ?? 100 // z 等于 100
let k = d ?? 100 // k 等于 100
let o = a || 100 // o 等于 100
let p = b || 100 // p 等于 100
let q = c || 100 // q 等于 100
let r = d || 100 // r 等于 100
??
只有当操作符左侧表达式的值为undefined
或者null
时,才会返回右侧的值。
||
只要操作符左侧表达式的值为 false
时,那么就会返回右侧的值。左侧的表达式会自动做布尔运算,因为0
和 空字符串''
做布尔运算,其值为 false
,所以o
和 p
的值等于 100
。
通过上面的比较可以发现,??
操作符的出现,是为了更准确的做空值判断,只有null
和undefined
才会被判定为空值, 0
和''
不会被判定为空值。
空值赋值操作符 ??=
只有当??=
左侧的值为null
或者 undefined
的时候,才会将右侧变量的值赋值给左侧变量,其他所有值都不会进行赋值,在某些场景下可以省略很多代码。
let a = null
let b = undefined
let c = 100
let d = 200
// 因为 a 的值为 null,所以会将 c 的值赋值给 a , 所以最终 a = 100
a ??= c
// 因为 b 的值为 undefined,所以会将 d 的值赋值给 b , 所以最终 b = 200
b ??= d
转载自:https://juejin.cn/post/7141289383046414366