Nullish Coalescing
The ?? operator — defaults that respect zero, empty strings, and false.
Basics
?? returns the right side only for null/undefined.
// ?? — nullish coalescing operator: // Returns RIGHT side if LEFT is null or undefined // Returns LEFT side for everything else null ?? "default"; // "default" undefined ?? "default"; // "default" // These are NOT nullish — left side is returned: 0 ?? "default"; // 0 "" ?? "default"; // "" false ?? "default"; // false NaN ?? "default"; // NaN // Think of it as: "use this value, unless it's missing" const name = user.name ?? "Anonymous"; const count = response.total ?? 0; const enabled = settings.darkMode ?? true;
Nullish = null or undefined
Only these two values trigger the default. Zero, empty string, false, and NaN are all valid values that ?? preserves.
vs || (OR)
The key difference: what triggers the fallback.
// || triggers fallback for ALL falsy values: 0 || 42; // 42 (0 is falsy) "" || "default"; // "default" (empty string is falsy) false || true; // true (false is falsy) null || "backup"; // "backup" // ?? triggers fallback ONLY for null/undefined: 0 ?? 42; // 0 ← preserves zero! "" ?? "default"; // "" ← preserves empty string! false ?? true; // false ← preserves false! null ?? "backup"; // "backup"
|| catches all falsy values (0, '', false, null, undefined, NaN). ?? only catches null and undefined.
1 / 2
| Value | x || "fb" | x ?? "fb" |
|---|---|---|
| null | "fb" | "fb" |
| undefined | "fb" | "fb" |
| 0 | "fb" | 0 |
| "" | "fb" | "" |
| false | "fb" | false |
| "hi" | "hi" | "hi" |
??= Assignment
Assign only if the variable is null/undefined.
// Nullish coalescing assignment (??=):
// Assigns only if the left side is null/undefined
let name = null;
name ??= "Anonymous";
// name = "Anonymous" (was null)
let count = 0;
count ??= 10;
// count = 0 (was NOT null/undefined, so unchanged!)
// Equivalent to:
// x ??= y → x = x ?? y → if (x == null) x = y;
// Useful for lazy initialization:
function getCache() {
this.cache ??= {}; // create once
this.cache.hits ??= 0; // init counter once
return this.cache;
}
// Compare with other assignment operators:
let a = null;
a ||= "default"; // assigns if falsy (0, "", false, null, undefined)
a &&= "value"; // assigns if truthy
a ??= "default"; // assigns if null/undefined ONLYWith ?.
The perfect pair — safe access + safe defaults.
// ?. + ?? = safe access with fallback:
const theme = user?.settings?.theme ?? "light";
const avatar = profile?.images?.avatar ?? "/default.png";
const count = response?.data?.items?.length ?? 0;
// Without this combo (old verbose way):
const theme = user && user.settings && user.settings.theme
? user.settings.theme
: "light";
// Real-world API handling:
async function getUser(id) {
const res = await fetch(`/api/users/${id}`);
const data = await res.json();
return {
name: data?.name ?? "Unknown",
email: data?.email ?? null,
avatar: data?.profile?.avatar?.url ?? "/placeholder.png",
role: data?.permissions?.role ?? "viewer",
lastLogin: data?.activity?.lastLogin ?? "Never",
};
}
// DOM with fallback:
const title = document.querySelector("h1")?.textContent ?? "Untitled";
const width = element?.getBoundingClientRect()?.width ?? 0;Patterns
Common patterns with nullish coalescing.
// 1. Configuration with defaults:
function createServer(options) {
const port = options?.port ?? 3000;
const host = options?.host ?? "localhost";
const debug = options?.debug ?? false;
// port: 0 is valid, debug: false is valid
}
// 2. Chaining with ??:
const value = primary ?? secondary ?? tertiary ?? "fallback";
// First non-nullish value wins
// 3. Form values (empty string is valid):
const search = input.value ?? "";
// Only defaults if value is somehow null/undefined
// Preserves "" (user cleared the field intentionally)
// 4. Numeric defaults:
const timeout = config.timeout ?? 5000;
const retries = config.retries ?? 3;
const delay = config.delay ?? 0; // 0 is preserved!
// ⚠️ Cannot mix with || or && without parentheses:
// a ?? b || c → SyntaxError!
// a || b ?? c → SyntaxError!
// Must use parens:
(a ?? b) || c // ✓
a ?? (b || c) // ✓FAQ
Common questions about nullish coalescing.