Learn the JavaScript nullish coalescing operator (??) and why it's safer than || for default values. Runnable examples covering all the edge cases.
The nullish coalescing operator (??) is an ES2020 operator that returns its right-hand side only when the left-hand side is null or undefined. It's designed to replace || for default values, because || treats every falsy value (0, '', false) as 'missing' — which is almost never what you want when 0 or empty string are valid inputs.
a ?? b returns a unless a is null or undefined, in which case it returns b. That's it — 0, '', false, and NaN all pass through unchanged.
a || b returns b whenever a is any falsy value. This causes bugs when 0 or '' are legitimate values (e.g. count ?? 10 returns 0 correctly; count || 10 incorrectly returns 10).
obj.x ??= default assigns default to obj.x only if obj.x is null or undefined. It's the assignment sibling of ??, parallel to ||= and &&=.
JavaScript forbids a ?? b || c without explicit parentheses to avoid precedence confusion. Write (a ?? b) || c or a ?? (b || c) to make the intent clear.
Use ?? whenever you want to supply a default only when a value is genuinely absent (null or undefined), especially for numeric and string inputs where 0 and '' are valid. Use || only when any falsy value should trigger the fallback, like text form inputs where empty string means 'user entered nothing'.
// || treats all falsy values as missing — buggy for 0
const count = 0;
console.log(count || 10); // 10 (wrong — 0 is a valid count)
console.log(count ?? 10); // 0 (correct)
// Same for empty string
const name = "";
console.log(name || "Guest"); // "Guest"
console.log(name ?? "Guest"); // ""
// Real use case: config merging
function greet(options = {}) {
const retries = options.retries ?? 3; // keeps 0
const prefix = options.prefix ?? "[app]"; // keeps ""
return `${prefix} retries=${retries}`;
}
console.log(greet({ retries: 0, prefix: "" }));
// Nullish assignment
const config = { debug: false };
config.debug ??= true; // stays false
config.timeout ??= 5000; // becomes 5000
console.log(config);
Open this example in the TryJS playground to edit and run the code instantly in your browser — no signup needed.
|| returns the right-hand side for any falsy value (0, '', false, null, undefined, NaN). ?? returns it only for null and undefined. Use ?? when you want 0 or '' to be valid values rather than triggering the fallback.
Whenever the left side is a nullable value and the fallback should only apply to null/undefined — counts, optional props, API response fields. If falsy-ish 'missing' semantics are what you want (like trimming a text input), stick with ||.
Only with explicit parentheses. a ?? b || c is a syntax error — write (a ?? b) || c or a ?? (b || c). This rule exists so developers can't accidentally rely on confusing precedence.
Logical nullish assignment. obj.x ??= default assigns default to obj.x only if obj.x is currently null or undefined. Shorthand for obj.x = obj.x ?? default.