JS 中的 ? 操作符(? / ?. / ?? / ??= ||= &&=)

一、 三目运算 ?

// if 逻辑判断
if (x > y) {
    z = 100
} else {
    z = 200
}
// 三目运算简化 if
z = x > y ? 100 : 200

二、可选链操作符 ?.

let demo = { name: '前端小玖', age: 20 }
console.log('昵称', demo.nickName.toString())

执行上面的代码,你会得到以下错误:

错误消息

因为 demo 对象上不存在 nickName 属性,所以当读取 demo.nickName 时,你得到的将会是 undefined,而 undefined 是没有 toString() 方法的,所以就报错了。

也就是说,当你要访问某个对象的属性或者调用某个对象上的方法时,如果这个对象的值为 undefined 或者 null,那么语句执行就会报错,举例如下:

// 报错: null 是不存在 push 方法的
let arr = null
arr.push(1)

// 报错: obj中不存在 c 属性,所以 obj.c 的值为 undefined,
// 那么再访问 c (undefined) 中的 d 属性是行不通的
let obj = { a: 1, b: 2 }
console.log(obj.c.d)

以往我们的解决方案是加一层判断,确保访问的对象不为 undefined 或者 null,我们才做后续操作,具体代码如下:

let demo = { name: '前端小玖', age: 20 }

// 确保 demo.nickName 不为 null / undefined
// 我们才调用 nickName.toString() 方法
if (demo.nickName) {
    console.log('昵称', demo.nickName.toString())
}

上面的代码虽然解决了问题,但是写起来太繁琐,不够优雅,所以新版 JS 增加了可选链操作符来简化这一过程。上面的代码用可选链操作符简化如下:

let demo = { name: '前端小玖', age: 20 }
console.log('昵称', demo.nickName?.toString())

所以 ?. 可选链操作符的作用就是,如果 demo 对象的 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

或赋值运算符 ||=

x ||= y相当于x || (x = y)

user.id = user.id || 1 // 当user.id不存在时默认初始化为1
user.id ||= 1 // 新写法

与赋值运算符 &&=

x &&=y相当于x && (x = y)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值