运算符
ES2016 新增了 指数运算符 2 ** 2 let a = c a **= b let a = 2 a **= 3 等同于 a = a * a * a
指数运算符连用从右开始运算
ES2020 引入了链判断运算符
比如以前判断:
(错误写法,如下:)
[错误的原因:如果 message.body.user.firstName 的值本身就是 false 或者 0 ,而该值不会被返回,而我们的本意是 message.body.user.firstName 的值为null或undefined 返回 default,当 message.body.user.firstName 该返回就是 0 或 false 的时候我就想返回 0 或 false]
const firstName = message.body.user.firstName || 'default'
(经过判断正确1写法,如下:)
const firstName = (message && message.body && message.body.user && message.body.user.firstName) || 'default'
运用新的ES2020 链判断运算符 (?.)
const firstName = message?.body?.user?.firstName || 'default'
首先判断 message每一步是否存在,如果不存在,不在继续往下运算,直接返回undefined
对于一些可能没有办法实现的方法,这个运算符也能发挥出作用
比如:this.upload() => return false
if (this.upload?.() === false) {
// 校验失败 返回
return
}
在上述if中,如果this.找不到upload,会直接返回undefined,undefined === false 返回 true,则不会走到下面逻辑中 (短路机制)
a?.b // 等同于 a == null ? undefined : a.b
a?.[x] // 等同于 a == null ? undefined : a[x]
a?.b() // 等同于 a == null ? undefined : a.b()
a?.() // 等同于 a == null ? undefined : a()
最后两种形式,如果b不是函数,会报错,最后一种,如果a不是函数,会报错
综上
链判断运算符可以判断 对象上的属性是否存在,即:obj.item => obj?.item
判断 函数或对象上的方法是否存在,即:func?.(...args)
小例子:
let hex = "#C0FFEE".match(/#([A-Z]+)/i)?.[1];
返回:C
(遇到0就没有继续向下匹配)返回C,单个字符,而没有#c 返回是由于?.后面的[1]
短路机制
括号影响,?. 对括号外面没有影响
报错场合:new a?.() / new a?.b() /
右侧有模板字符串的 a?.`{b}` / a?.b`{c}`
左侧是 super 的 super?.() / super?.foo
链运算符用于赋值运算符左侧的 a?.b = c
右侧不能为十进制数值 为了保证兼容以前的代码,允许 foo?.3:0 被解析成 foo ? .3 : 0, 所以如果跟一个十进制数字,?.运算符就会被分开,不构成一个完整的运算符,而被解析成了一个三元表达式,后面的 .3 会被看成一个小数。
ending...
(该文于很早之前看的公众号推文,整理笔记时未能找到原址链接...)



