ES6运算符的扩展🙌

133 阅读3分钟

空值合并运算符 ??

空值合并运算符??是一个逻辑操作符, 当左侧的操作数为null或者undefined时, 返回侧操作数, 否则返回侧操作数。

  • 左侧操作符是null。

    const  data = null;
    const  str = data?? '我是一个空值'
    console.log(str)  //我是一个空值
  • 左侧操作符是undefined

    const  data = undefined;
    const  str = data?? '我是一个空值'
    console.log(str)  //我是一个空值
  • 左侧操作符是其他

    const  data = '哈哈';
    const  str = data?? '我是一个空值'
    console.log(str)  //哈哈
  • 为变量赋默认值

由于 ||是一个布尔逻辑运算符, 左侧的操作数会被强制转化为布尔值用于求值。 任何假值(0null, NaN, '', undefined)都不会被返回。 这导致如果使用 0,'', NaN做为有效值, 就不会正常返回。

空值合并操作符可以避免这种陷阱,其只在第一个操作数为nullundefined 时(而不是其它假值)返回第二个操作数:

    let str = ''
    
    let str2 = str || 'Hello world';
    console.log(str2); // Hello world

    let str3 = str ?? 'Hi neighborhood';
    console.log(str3); // ''

逻辑空赋值 ??=

逻辑空运算符x??=y 仅在x 是 null或者undefined时对其赋值。

    const p = {
        name:'Iric'
    }
    p.name??='张三'
    console.log(p.name)  //Iric
    p.age??= 23
    console.log(p.age)  //23

逻辑空赋值的语法短路也意味着 x ??= y 等价于:x ?? (x = y);

链判断运算符 ?.

可选链操作符?.允许读取位于对项链深处的属性的值, 而不必明显验证链中的每个引用是否有效。?.操作符的功能类似.链式操作符。 不同之处在于, 在引用为(nullundefined)的情况下不会引起错误。 改表达式的短路返回值时undefiende。

    const p = {
          name:'Iric',
          friends:{
              name:'Lisa'
          }
      }
     const name = p.friends?.name;
     console.log(name)//Lisa
     const age = p.friends?.age;
     console.log(age) /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()

(1)短路机制

本质上,?.运算符相当于一种短路机制,只要不满足条件,就不再往下执行。

a?.[++x]
// 等同于
a == null ? undefined : a[++x]

上面的代码, 如果aundefined或者null, 那么x就不会递增运算, 也就是说, 链判断运算符一旦为真, 右侧的表达式就不会在求值。

(2)括号的影响

如果属性链有圆括号, 连判断运算符对圆括号外部没有影响, 只对圆括号内部有影响。

(a?.b).c
//等价于
(a == null? undefined: a.b).c

上面代码中, ?.对圆括号外部没有影响, 不管a对象是否存在, 圆括号后面的.c总是会执行。

一般来说, 使用?.运算符的场合, 不应该使用圆括号。

指数运算符 **

指数运算符(**):这个运算符的一个特点是右结合,而不是常见的左结合。多个指数运算符连用时,是从最右边开始计算的。

// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2

指数运算符可以与等号结合,形成一个新的赋值运算符(**=)。

  let a = 1.5;
  a **= 2;
  // 等同于 a = a * a;

  let b = 4;
  b **= 3;
  // 等同于 b = b * b * b;

总结

这三个运算符||=&&=??=相当于先进行逻辑运算,然后根据运算结果,再视情况进行赋值运算

// 或赋值运算符
x ||= y
// 等同于
x || (x = y)

// 与赋值运算符
x &&= y
// 等同于
x && (x = y)

// Null 赋值运算符
x ??= y
// 等同于
x ?? (x = y)