Nullish coalescing in JavaScript: a fallback value that respects zero

The ?? operator returns a fallback only when the tested value is null or undefined, unlike || which also wipes out zero and empty strings.
3 min read
Believemy logo

For twenty years, a fallback value in JavaScript was written with two vertical bars. It worked, except when the data was zero, an empty string or false, which is to say precisely in the cases that matter.


Definition

Nullish coalescing, written with two question marks, returns the left operand unless it is null or undefined: only then does it return the right one.

JAVASCRIPT
console.log(null ?? "fallback");       // "fallback"
console.log(undefined ?? "fallback");  // "fallback"
console.log(0 ?? "fallback");          // 0
console.log("" ?? "fallback");         // ""
console.log(false ?? "fallback");      // false

The last three lines capture the whole point of the operator. Zero, the empty string and false are valid answers, and it lets them through untouched.


The difference from ||, in one comparison

The older operator does not test emptiness, it tests truthiness. So it replaces the eight values described in Truthy and falsy, not merely the two empty ones.

Tested valueWith ??With ||
nullThe fallbackThe fallback
undefinedThe fallbackThe fallback
00The fallback
""""The fallback
falsefalseThe fallback

Those last three rows are bugs waiting to happen: a quantity of zero displayed as not provided, a deliberately empty comment replaced by default text, a cleared checkbox that ticks itself back on.

Good to know

Cases remain where || is the right pick, when an empty string really should count as missing. A title typed then wiped often deserves a fallback. The question to ask is simple: are zero and the empty string legitimate answers here?


Two syntax rules worth knowing

The first is a constraint of the language, the second a convenience that landed slightly later.

JAVASCRIPT
const a = null, b = "value", c = "fallback";

// Forbidden: mixing with || or && without parentheses
// const x = a ?? b || c;  // SyntaxError

console.log((a ?? b) || c); // "value"

// Conditional assignment: fills in only when empty
const options = { limit: 0 };
options.limit ??= 50;
options.page ??= 1;

console.log(options); // { limit: 0, page: 1 }

Refusing the unparenthesized mix is deliberate: precedence between the two operators is far from obvious, and the standards committee preferred a clear error over a silent ambiguity. The second form, with the equals sign, is very handy for completing an options object without overwriting what the caller supplied.


Frequently asked questions

Question

When should ?? be preferred over ||?

As soon as the tested value can legitimately be zero, an empty string or false. That covers most numeric data, optional text fields and boolean preferences. When in doubt, ?? is the safer pick, since it only acts on genuine emptiness.


Question

Does it work with optional chaining?

Yes, and the two combine very naturally. Optional chaining (?.) prevents the crash while reading, then ?? supplies the displayable value. Writing data?.total ?? 0 has become a reflex as soon as an API response is involved.


Question

Is it available everywhere?

It entered the standard in 2020 and is supported by every current browser as well as by Node.js. On a project that must reach older environments, the build tool automatically rewrites it into an equivalent compatible form.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.