1. 指数运算符( ** )
- 注意 运算符的特点是右结合,而不是左结合。多个运算符连用时,从最右边开始计算。
// 相当于 2 ** (3 ** 2) 2 ** 3 ** 2 // 512
- 指数运算符可以与等号结合,形成一个新的赋值运算符( **= )
let a = 1.5; a **= 2; // 等同于 a = a * a; let b = 4; b **= 3; // 等同于 b = b * b * b;
2. 链判断运算符 ( ?. )
const firstName = message?.body?.user?.firstName || 'default';
const fooValue = myForm.querySelector('input[name=foo]')?.value
上面代码使用了?.
运算符,直接在链式调用的时候判断,左侧的对象是否为null
或undefined
。如果是的,就不再往下运算,而是返回undefined
。
三种写法
- obj?.prop // 对象属性是否存在
- obj?.[expr] // 同上
- func?.(…args) // 函数或对象方法是否存在
下面是?.运算符常见形式,以及不使用该运算符时的等价形式。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()
运算符的注意点
- 短路机制
- 括号的影响:对圆括号外部没有影响
- 报错场合:构造函数、链运算符右侧有模板字符串、链运算符左侧是super关键字、链运算符用于赋值运算符左侧
- 链运算符右侧不得为十进制数值
3. Null 判断运算符 ( ?? )
它的行为类似||,但是只有运算符左侧的值为null或undefined时,才会返回右侧的值。
跟链判断运算符?.配合使用,为null或undefined的值设置默认值。
const animationDuration = response.settings?.animationDuration ?? 300;
上面代码中,如果response.settings
是null或undefined,或者response.settings.animationDuration
是null或undefined,就会返回默认值300。也就是说,这一行代码包括了两级属性的判断。
4. 逻辑赋值运算符
先进行逻辑运算,然后根据运算结果,再视情况进行赋值运算。
1. 或赋值运算符 ( ||= )
x ||= y // 等同于 x || (x = y)
2. 与赋值运算符 ( &&= )
x &&= y // 等同于 x && (x = y)
3. Null 赋值运算符 ( ??= )
x ??= y // 等同于 x ?? (x = y)
4. 用途
为变量或属性设置默认值