'||=', '&&=', and '??=' fuse a logical check with an assignment in a single operator, replacing common 'if (condition) { x = y }' patterns with a single expression.
1Logical Assignment Operators | JavaScript Tutorial - In-Depth Guide Part 1
'||=' assigns the right-hand value only if the variable is currently falsy.
let title = '';
title ||= 'Untitled';The ||= Operator
2Logical Assignment Operators | JavaScript Tutorial - In-Depth Guide Part 2
'&&=' assigns the right-hand value only if the variable is currently truthy — the inverse condition of '||='.
let user = { name: 'Ana' };
user.name &&= user.name.trim();The &&= Operator
3Logical Assignment Operators | JavaScript Tutorial - In-Depth Guide Part 3
'??=' assigns the right-hand value only if the variable is currently null or undefined — the precise version of '||=' for default-initialization.
const cache = {};
cache.hits ??= 0;
cache.hits++;The ??= Operator
4Logical Assignment Operators | JavaScript Tutorial - In-Depth Guide Part 4
All three operators short-circuit — the right-hand side is only evaluated when the assignment will actually happen, avoiding unnecessary work or side effects.
obj.value ??= computeExpensiveDefault(); // only runs if neededLazy Evaluation
5Logical Assignment Operators | JavaScript Tutorial - In-Depth Guide Part 5
Choosing the right one comes down to intent: '??=' for 'set if missing', '||=' for 'set if falsy', '&&=' for 'update only if already present'.
settings.theme ??= 'light'; // was it ever set?
form.error ||= 'Invalid input'; // is it currently empty?
user.bio &&= user.bio.trim(); // transform only if presentChoosing the Right One
6Step-by-Step Breakdown
'||=' assigns the right-hand value only if the variable is currently falsy.
'&&=' assigns the right-hand value only if the variable is currently truthy — the inverse condition of '||='.
Checkpoint: Does x &&= y assign y to x when x is currently 0?
- →Yes, it always assigns
- →No, 0 is falsy so &&= skips the assignment
'??=' assigns the right-hand value only if the variable is currently null or undefined — the precise version of '||=' for default-initialization.
All three operators short-circuit — the right-hand side is only evaluated when the assignment will actually happen, avoiding unnecessary work or side effects.
Checkpoint: If obj.value already equals false, does obj.value ??= true overwrite it?
- →Yes, false gets replaced
- →No, false is not nullish so it is left untouched
Choosing the right one comes down to intent: '??=' for 'set if missing', '||=' for 'set if falsy', '&&=' for 'update only if already present'.
Next, we'll explore 'Default Parameters'.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Use ??= to Preserve Explicit Falsy Accessibility Flags
A component prop like `showLabel ??= true` correctly respects an explicit `showLabel={false}` passed by a consumer who wants to hide a visible label in favor of a custom aria-label, whereas `||=` would silently override that choice.
SEO Implications
- 1
No Direct SEO Impact
These operators are a code-clarity and correctness improvement; their effect on search visibility is only indirect, through preventing default-value bugs that could corrupt rendered content.
Best Practices
Use `??=` for Lazy Initialization of Config/Cache Values
It is the only one of the three that correctly leaves legitimate falsy values (0, false, "") untouched while still filling in genuinely missing ones.
Don't Overuse Logical Assignment for Complex Conditions
These operators are best for simple, single-variable conditional assignment; anything requiring multiple conditions is clearer as an explicit if statement.
Frequent Bugs
Using `count ||= 10` to default a counter incorrectly resets a legitimate `count = 0` back to 10.
Use `count ??= 10` instead, which only assigns when count is null or undefined, correctly preserving an intentional 0.
Expecting `&&=` to run its right-hand side even when the variable is falsy, then being surprised a side-effecting function on the right never executes.
Remember &&= short-circuits: the right side runs only when the left side is already truthy. Restructure the logic or use a plain if statement if the side effect must always run.
Real-World Examples
Memoizing an Expensive Computation on an Object
A reporting module needed to compute an expensive aggregate value once per object and cache it, without recomputing on every access.
function getTotal(report) {
report._cachedTotal ??= report.items.reduce((sum, i) => sum + i.amount, 0);
return report._cachedTotal;
}