JavaScript Nullish Coalescing (??) vs Logical OR (||) — Explained | TryJS

Learn the JavaScript nullish coalescing operator (??) and why it's safer than || for default values. Runnable examples covering all the edge cases.

Overview

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.

How It Works

Nullish means only null and undefined

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.

Compare with logical OR (||)

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).

Nullish assignment (??=)

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 &&=.

Cannot mix with && or || without parens

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.

Common Mistakes

When to Use It

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'.

Runnable Example

// || 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.

Frequently Asked Questions

What is the difference between ?? and || in JavaScript?

|| 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.

When should I use nullish coalescing?

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 ||.

Can I combine ?? with && or ||?

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.

What is the ??= operator?

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.