&&=、||= 和 ??= 分别有什么作用?

12

我在 v15.0.1 中见过这些语法:&&=||=??=。但我不知道它们的作用是什么。有人知道吗?


当前被接受的答案不幸地包含了一些错误信息。也许自从它发布以来,实现方式已经发生了变化,因为逻辑赋值运算符在那时仍处于早期阶段。 - leonheess
@leonheess 我已经查看了它,但没有发现任何错误,你能指出具体哪里有问题吗?谢谢。 - CertainPerformance
@CertainPerformance,请将您的“等效代码”与此处或我的答案中的等效部分进行比较。 - leonheess
3个回答

11

这些被称为逻辑赋值运算符,总共有三种:

  1. 逻辑与赋值运算符 (&&=)
  2. 逻辑或赋值运算符 (||=)
  3. 空值合并赋值运算符 (??=)

从根本上讲,它们都做同样的事情:将逻辑运算符 &&??|| 放在 = 前面,如 x logical-operator= y,可以重写为 x logical-operator (x = y)。它们的唯一目的是替换更冗长的代码:

  1. x &&= y does nothing if x is not truthy and changes x's value to y if x is truthy. It is the same as:

    if (x) {
      x = y 
    }
    
  2. x ||= y does nothing if x is truthy and changes x's value to y if x is not truthy. It is the same as:

    if (!x) {
      x = y 
    }
    
  3. x ??= y does nothing if x is not nullish and changes x's value to y if x is nullish. It is the same as:

    if (x === null || x === undefined) {
      x = y 
    }
    
以下是一些例子,以进一步帮助您理解它们:
const y = 'other value'

let def   = 'initial'    // truthy value
let zero  = 0            // not truth value
let undef = undefined    // nullish value

def   &&= y    // def = 'other value'
zero  &&= y    // zero = 0
undef &&= y    // undef = 'undefined'

def   ||= y    // def = 'initial'
zero  ||= y    // zero = 'other value'
undef ||= y    // undef = 'other value'

def   ??= y    // def = 'initial'
zero  ??= y    // zero = 0
undef ??= y    // undef = 'other value'

7

这些是新的逻辑赋值操作符,它们类似于更常见的操作符,如*=+=等。

someVar &&= someExpression大致相当于someVar = someVar && someExpression

someVar ||= someExpression大致相当于someVar = someVar || someExpression

someVar ??= someExpression大致相当于someVar = someVar ?? someExpression

我说“大致”是因为有一个区别-如果右侧表达式未使用,则不会调用可能的setter。所以它更接近于:

someVar &&= someExpression就像

if (!someVar) {
  someVar = someExpression;
}

等等。一个 setter 没有被调用的事实 不太可能 对脚本产生影响,但这并非不可能。这与其他传统的简写赋值运算符不同,它们无条件地对变量或属性进行赋值(从而调用 setter)。以下是一个代码片段以说明:

const obj = {
  _prop: 1,
  set prop(newVal) {
    this._prop = newVal;
  },
  get prop() {
    return this._prop;
  }
};

// Setter does not get invoked:
obj.prop ||= 5;

??,如果你不熟悉它的话,是空值合并运算符。如果左侧为nullundefined,则将评估为右侧。


1
Mozilla建议使用&&=与您提出的简化略有不同,但这并不是太大的区别。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment - Anirudh

1

a = a || b 等同于 a ||= b => 如果 a 为真,则返回 a,如果 a 为假,则返回 b

a = a && b 等同于 a &&= b => 如果 a 为真,则返回 b,如果 a 为假,则返回 a

a = a ?? b 等同于 a ??= b => 如果 anullundefined,则返回 b,如果 a 为真,则返回 a

注意:nullundefined""0NaN 均为假

例子:

let a = -22
const b = false

a &&= b
console.log(a)   // false

let a = 0
const b = 'hello'

a ||= b
console.log(a)   // hello

let a = false
let b = true

a ??= b
console.log(a)   // false

let a = null
let b = true

a ??= b
console.log(a)   // true

如果您不理解,请再次阅读!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接