Javascript (ES2021) now supports the ability to combine logical operations and assignment with the new operators &&=
, ||=
, and ??=
. Previously, compound assignment operators were only possible with mathematical and bitwise operations.
Logical AND assignment &&=
The logical AND assignment x &&= y
operator performs assignment only if x
is truthy. For example:
let a = 1;
let b = 0;
a &&= 2;
console.log(a); // output: 2
b &&= 2;
console.log(b); // output: 0
Short-circuit evaluation
If the left-hand expression is falsy, it is short-circuit evaluated and the right-hand expression is not evaluated, so the value of b
is not reassigned because 0 is falsy.
a &&= 2
is equivalent to a && (a = 2)
, and the value of a
is reassigned because it was originally truthy.
Logical OR assignment ||=
The logical OR assignment x ||= y
operator only assigns if x
is falsy.
const a = 50;
const b = '';
a ||= 10;
console.log(a); // output: 50
b ||= 'string is empty.';
console.log(b); // output: "string is empty."
Short-circuit evaluation
From the above example, a ||= 10
is equivalent to a || (a = 10)
, but because the value of a
is truthy, it is short-circuit evaluated and the right-hand assignment is not evaluated.
If you are checking against a falsy value such as an empty string or 0, ||=
must be used, otherwise the logical nullish assignment operator ??=
should be used to check for null
or undefined
values.
Logical nullish assignment ??=
The logical nullish assignment x ??= y
operator only assigns if x
is null
or undefined
.
const a = { limt: 50 };
a.limit ??= 10;
console.log(a.limit); // output: 50
a.speed ??= 25;
console.log(a.speed); // output: 25
Short-circuit evaluation
A logical nullish assignment expression is short-circuit evaluated to the left-hand side expression if the left-hand side is neither null
nor undefined
.
In the above example, the reassignment of a.limit
is not performed because its value is defined as 50, which is not null
or undefined
.
a.speed
would initially evaluate to undefined
, so the right-hand expression is evaluated, which is equivalent to a.speed = 25
, and now a = {limit: 50, speed: 25}
.
Top comments (1)
I like that we have the option to do this now, but I'm wondering if it will impact legibility in a negative way. Just reading the code snippets I understand what's going on, but I have to pause and think about it.
Then again, this might just be a matter of getting used to it and using it more often.