Logical Assignment ??= &&= ||=
Assign only when a condition holds, in one short-circuiting operator.
Syntax
a ||= b
a &&= b
a ??= bES2021 fused logical operators with assignment. Each one assigns only if its logical test would proceed, and each short-circuits so the right side is skipped otherwise.
| Operator | Assigns when left is... | Long form |
|---|---|---|
a ||= b | falsy | a || (a = b) |
a &&= b | truthy | a && (a = b) |
a ??= b | null / undefined | a ?? (a = b) |
The nuance that matters
They short-circuit the assignment itself. obj.x ??= compute() does not even call compute() if obj.x already has a value, and it does not trigger setters. That makes ??= the cleanest lazy-initialise / memo primitive.
cache[key] ??= expensive(key); // compute once, reuse afterExample
Loading editorβ¦
Press Run to execute the code.
When to use it
- Use ??= to lazily assign a default timeout to a config object only if the key is absent.
- Use ||= to set a fallback username when the stored value is an empty string.
- Use &&= to update a cached result only when the cache entry already exists.
More examples
Nullish assignment ??=
??= assigns only when the current value is null or undefined, preserving the intentional 0 for port.
const cfg = { port: 0 };
cfg.host ??= "localhost";
cfg.port ??= 3000; // 0 is not null/undefined, kept
console.log(cfg); // { port: 0, host: "localhost" }OR assignment ||=
||= assigns the right-hand side when the left is falsy, providing a fallback for empty strings.
let username = "";
username ||= "Anonymous";
console.log(username); // "Anonymous" β empty string is falsyAND assignment &&=
&&= replaces the left side only when it is already truthy, useful for enriching existing values.
const cache = { user: { name: "Alice" } };
cache.user &&= { ...cache.user, lastSeen: Date.now() };
console.log(cache.user.name); // "Alice" β updated in place
Discussion