11

I have seen this syntax in v15.0.1: &&=, ||= and ??=. But I don't know what it does. Does anyone know?

leonheess
  • 16,068
  • 14
  • 77
  • 112
ecoplaneteer
  • 1,918
  • 1
  • 8
  • 29
  • The current accepted answer unfortunately contains some incorrect information. Maybe the implementation changed since it was posted as the logical assignment operators were still in early stages back then. – leonheess May 13 '21 at 23:04
  • @leonheess I looked over it but don't see anything wrong, could you point out what exactly is incorrect? Thanks – CertainPerformance Jun 01 '21 at 01:10
  • @CertainPerformance Compare the equivalent section [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment) or in my answer with your "equivalent code". – leonheess Jun 01 '21 at 07:22

3 Answers3

10

Those are called Logical Assignment Operators and there are three in total:

  1. Logical AND assignment (&&=)
  2. Logical OR assignment (||=)
  3. Logical nullish assignment (??=)

Fundamentally they all do the same: The logical operators &&, ?? and || in front of the = as in x logical-operator= y can be rewritten as x logical-operator (x = y). Their only purpose is to replace more verbose code:

  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 
    }
    

Here are some examples to further your understanding of these:

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'
leonheess
  • 16,068
  • 14
  • 77
  • 112
7

These are the new logical assignment operators. They're similar to the more familiar operators like *=, +=, etc.

someVar &&= someExpression is roughly equivalent to someVar = someVar && someExpression.

someVar ||= someExpression is roughly equivalent to someVar = someVar || someExpression.

someVar ??= someExpression is roughly equivalent to someVar = someVar ?? someExpression.

I say "roughly" because there's one difference - if the expression on the right-hand side isn't used, possible setters are not invoked. So it's a bit closer to:

someVar &&= someExpression is like

if (!someVar) {
  someVar = someExpression;
}

and so on. (The fact that a setter isn't invoked is unlikely to have an effect on the script, but it's not impossible.) This is unlike the other traditional shorthand assignment operators which do unconditionally assign to the variable or property (and thus invoke setters). Here's a snippet to demonstrate:

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

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

??, if you aren't familiar with it, is the nullish coalescing operator. It will evaluate to the right-hand side if the left-hand side is either null or undefined.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • 1
    Mozilla suggests &&= is slightly different than the simplification you posed https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment, but its not too big of a difference. – Anirudh Oct 31 '20 at 01:25
1

a = a || b is equivalent to a ||= b => if a is true, a return but if a is false b return.

a = a && b is equivalent to a &&= b => if a is true, b return but if a is false a return.

a = a ?? b is equivalent to a ??= b => if a just is null or undefined, b return but if a is true a return.

note: null, undefined, "", 0, NaN are false

examples:

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

If you do not understand, read it again!

Ramin eghbalian
  • 2,348
  • 1
  • 16
  • 36