Frontend Development 6 min read

Mastering JavaScript’s Nullish Coalescing (??) Operator: When to Use It Over ||

Learn how JavaScript’s nullish coalescing (??) operator works, its key differences from the logical OR (||) operator, and see practical examples—from handling default form values to chaining defaults and combining with optional chaining—plus performance considerations and advanced patterns.

JavaScript
JavaScript
JavaScript
Mastering JavaScript’s Nullish Coalescing (??) Operator: When to Use It Over ||

JavaScript, as an evolving language, continuously introduces new features to solve developers' pain points. ES2020 introduced the nullish coalescing operator (??), a simple yet powerful tool that fundamentally changes how we handle default values and nulls.

Basic concept: What is the ?? operator

The nullish coalescing operator (??) returns the right-hand operand when the left-hand operand is

null

or

undefined

; otherwise it returns the left-hand operand. This differs fundamentally from the logical OR (||) operator.

<code>const value1 = null ?? 'default'; // 'default'
const value2 = undefined ?? 'default'; // 'default'
const value3 = false ?? 'default'; // false
const value4 = 0 ?? 'default'; // 0
const value5 = '' ?? 'default'; // ''
</code>

Key differences between ?? and ||

Before understanding the power of ?? we need to understand its difference from ||:

<code>// Using ||
const count = userCount || 10; // when userCount is 0, count becomes 10

// Using ??
const count = userCount ?? 10; // when userCount is 0, count remains 0
</code>

The || operator treats all falsy values (0, '', false, NaN, etc.) as needing the default, whereas ?? only uses the default when the value is

null

or

undefined

.

Practical applications

1. Default values in form handling

<code>function processForm(data) {
  // Only use defaults when the value is truly missing
  const username = data.username ?? 'guest';
  const items = data.items ?? [];
  const quantity = data.quantity ?? 1; // allows quantity to be 0
  // process form logic...
}
</code>

2. Deep default values in configuration objects

<code>const config = {
  server: {
    port: 0, // valid but falsy
    host: '' // valid but falsy
  }
};
const userConfig = {};
// Properly handle deep configuration
const port = userConfig?.server?.port ?? config.server.port; // 0
const host = userConfig?.server?.host ?? config.server.host; // ''
</code>

3. API response handling

API response handling illustration
API response handling illustration

4. Chained defaults

?? can be chained to create a "default waterfall":

Chained defaults illustration
Chained defaults illustration

5. Perfect pairing with optional chaining (?.)

When combined with optional chaining, handling deeply nested objects becomes elegant:

<code>const userName = user?.profile?.preferences?.displayName ?? 'Guest';
</code>

6. Conditional function execution

<code>// Execute only if handler exists, otherwise use default handler
(customHandler ?? defaultHandler)(event);
</code>

7. Default handling for array elements

Array element defaults illustration
Array element defaults illustration

Advanced techniques

Combining with destructuring

<code>const { name, age, title = 'Developer', company = 'Unknown' } = employee ?? {};
</code>

This pattern handles the case where

employee

is null/undefined and also provides defaults for individual properties.

Using in classes

<code>class UserPreferences {
  constructor(settings) {
    this.theme = settings?.theme ?? 'light';
    this.fontSize = settings?.fontSize ?? 16;
    this.notifications = settings?.notifications ?? true;
    // Even if settings.volume is 0 it will be kept
    this.volume = settings?.volume ?? 0.5;
  }
}
</code>

Performance considerations

The ?? operator is not only syntactically concise; in some cases it also offers performance benefits because it only checks for

null

and

undefined

, avoiding the type‑coercion work performed by ||.

Although it appears simple, the double‑question‑mark operator solves a long‑standing pain point in JavaScript: correctly distinguishing between "null/undefined" and other falsy values.

JavaScript== operatoroptional chainingdefault valuesnullish coalescing
JavaScript
Written by

JavaScript

Provides JavaScript enthusiasts with tutorials and experience sharing on web front‑end technologies, including JavaScript, Node.js, Deno, Vue.js, React, Angular, HTML5, CSS3, and more.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.