The Codex / JavaScript / Optional Chaining & Nullish Operators

Optional Chaining & Nullish Operators

Safe property access with ?., nullish coalescing with ??, nullish assignment ??=, and logical assignment — eliminating null checks from modern JavaScript.

What it is, in plain English: Optional chaining (?.) lets you read a property deep in an object chain without checking if each level exists — if any part is null or undefined, the expression short-circuits and returns undefined instead of throwing. The nullish coalescing operator (??) returns the right side only when the left side is null or undefined — unlike || which also triggers on 0, '', and false.

Safer code with fewer null checks

Two of the most common bugs in JavaScript involve null and undefined: trying to access a property on something that doesn't exist, and using || for defaults when 0 or "" should be valid values. Three operators fix both problems cleanly.

?. — Optional chaining

Read a deeply nested property without crashing if something in the chain is missing.

const order = {
  id: 1,
  customer: {
    name: "Alice",
    address: {
      city: "Mumbai"
    }
  }
};

// Without ?.  — you need a chain of checks:
const city1 = order && order.customer && order.customer.address
              && order.customer.address.city;

// With ?. — one clean expression:
const city2 = order?.customer?.address?.city;
console.log(city2);  // "Mumbai"

// If any step is missing — returns undefined, no crash:
console.log(order?.billing?.address?.city);  // undefined
// Without ?.: TypeError: Cannot read properties of undefined
// ?. on method calls:
const user = { getName: () => "Bob" };

console.log(user.getName?.());      // "Bob"
console.log(user.getEmail?.());     // undefined (method doesn't exist — no crash)

// ?. on array access:
const first = null;
console.log(first?.[0]);   // undefined (not: TypeError: Cannot read properties of null)

?? — Nullish coalescing (the better default operator)

Use ?? instead of || when 0, "", or false are valid values that should NOT trigger the default.

// The || problem:
function setVolume(vol) {
  const volume = vol || 50;  // BUG: volume=0 becomes 50!
  console.log("Volume:", volume);
}
setVolume(0);   // Volume: 50  ← wrong!
setVolume(80);  // Volume: 80  ← correct

// The ?? fix:
function setVolumeFix(vol) {
  const volume = vol ?? 50;  // Only defaults when vol is null/undefined
  console.log("Volume:", volume);
}
setVolumeFix(0);      // Volume: 0   ← correct
setVolumeFix(80);     // Volume: 80  ← correct
setVolumeFix(null);   // Volume: 50  ← correct (null → use default)
setVolumeFix(undefined); // Volume: 50 ← correct

Combining ?. and ??

const config = {
  server: {
    port: 0,           // 0 is a valid port
    timeout: null,     // null means "not set"
  }
};

const port    = config?.server?.port    ?? 3000;   // 0 (not 3000 — 0 is valid)
const timeout = config?.server?.timeout ?? 5000;   // 5000 (null → default)
const host    = config?.server?.host    ?? "localhost"; // "localhost" (undefined → default)

console.log(port, timeout, host);  // 0  5000  "localhost"
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.