DEV Community

Cover image for Short-Circuiting in JavaScript
Lars Grammel for P42

Posted on • Updated on • Originally published at p42.ai

Short-Circuiting in JavaScript

In JavaScript, short-circuiting refers to the partial evaluation of expressions to avoid unnecessary computation. This blog post describes the short-circuiting operators and assignments in JavaScript and how to use them.

Short-Circuiting Operators: &&, ||, and ??

Short-circuiting operators only evaluate the right side of an expression when necessary.

For example, for the logical AND operator &&, when the left side of the operator is false, the right side of the operator will not change the result. The result is false regardless of whether the right side is true or false. Therefore JavaScript skips the evaluation of the right side and uses the value from the left side.

There are three short-circuiting binary operators in JavaScript:

A and B can be any expression. Their evaluation might invoke function and getter calls that can contain complex calculations or have side effects.
Because A and B can return any value, the three short-circuiting operators evaluate and return any value, not just booleans.

This means that you can use the short-circuiting operators for providing defaults (|| and ??), for checking nullish values (&&, before the optional chaining operator ?. was available), and for conditional rendering in React (&&).

// default values
a = a || 123; // assigns 123 to a if a is falsy
b = b ?? 123; // assigns 123 to b if b is nullish

// optional chaining with && ( .? is a modern alterative)
if (obj.m != null && obj.m() === '123') {
   // ...
}

// React: conditional rendering
return <>  
  {user != null &&
    <div>Welcome back, ${user.name}!</div>
  }
<>;
Enter fullscreen mode Exit fullscreen mode

Short-Circuiting Assignments: &&=, ||=, and ??=

With ES2021, you can use short-circuiting operators in assignment expressions (&&=, ||=, and ??=). Short-circuiting assignments are only carried out when the current variable or property value does not trigger short-circuiting. This behavior can help avoid unnecessary updates.

Here is an example(-Infinity is truthy):

let a = 3;
let b = 3;
let c = 0;
let d = 0;

a &&= -Infinity;
b ||= -Infinity;
c &&= -Infinity;
d ||= -Infinity;

console.log(a); // -Infinity
console.log(b); // 3 (short-circuiting ||, because 3 is truthy)
console.log(c); // 0 (short-circuiting &&, because 0 is falsy)
console.log(d); // -Infinity
Enter fullscreen mode Exit fullscreen mode

Refactoring Assignments with Short-Circuiting Operators

Short-circuiting assignments look very similar to regular assignments with short-circuiting operator expressions. One might think that they can be refactored as follows without changing the behavior:

a = a && x; /* becomes */ a &&= x;
a = a || x; /* becomes */ a ||= x;
a = a ?? x; /* becomes */ a ??= x;
Enter fullscreen mode Exit fullscreen mode

However, when I was developing the safety evaluation for the
'Push Operator into Assignment' and 'Pull Operator Out of Assignment' refactorings in P42, I discovered that those refactorings can lead to behavioral changes in some situations.

Consider the following example:

class C {
  constructor(name) {
    this.name = name;
  }

  get x() {
    return this._x;
  }

  set x(value) {
    console.log(`set ${this.name}.x to ${value}`);
    this._x = value;
  }
}
Enter fullscreen mode Exit fullscreen mode
// nullish coalescing operator
const a = new C("a");
a.x = a.x ?? 3;
a.x = a.x ?? 4;
console.log(a.x)
Enter fullscreen mode Exit fullscreen mode
// nullish assignment 
const b = new C("b");
b.x ??= 3;
b.x ??= 4;
console.log(b.x)
Enter fullscreen mode Exit fullscreen mode

Surprisingly, moving the operator into the assignment changes what operations are executed:

// output for nullish coalescing operator
"set a.x to 3"
"set a.x to 3"
3
Enter fullscreen mode Exit fullscreen mode
// output for nullish assignment 
"set b.x to 3"
3
Enter fullscreen mode Exit fullscreen mode

While these minor differences won't matter most of the time, it's good to be aware of them for two reasons:

  • they can cause breakages during refactoring because they change existing behavior
  • they can be beneficial to reduce the number of operations in performance hotspots

Summary

Short-circuiting operators in JavaScript (&&, ||, ??) evaluate their right-hand side expression only when necessary. Their assignment equivalents (&&=, ||=, ??=) only update a value when the current value would
cause the execution of the right side of the short-circuiting operator.

Top comments (0)