Q30 of 40 · JavaScript

How do optional chaining (`?.`) and nullish coalescing (`??`) work?

JavaScriptMidjavascriptoptional-chainingnullish-coalescinges2020null-safety

Short answer

Short answer: Optional chaining `?.` short-circuits to `undefined` if the left side is `null` or `undefined`, preventing TypeError on deep property access. Nullish coalescing `??` returns the right-hand side only when the left is `null` or `undefined` — unlike `||`, it preserves falsy values like `0` or `''`.

Detail

These two operators work together to safely access and default nested data without verbose null checks.

Optional chaining (?.):

  • a?.b returns undefined if a is null/undefined, otherwise evaluates a.b
  • a?.[key] for dynamic property access
  • fn?.(args) for optional function calls
  • Chains short-circuit: a?.b?.c stops at the first null/undefined

Nullish coalescing (??):

  • a ?? b returns b only when a is null or undefined
  • Preserves falsy values: 0 ?? 50; '' ?? 'default''''
  • Contrast with ||: 0 || 55 (0 is falsy, so the right side is used — often a bug)

Combining: user?.profile?.score ?? 0 safely navigates to score and defaults to 0 if any segment is nullish.

In test automation: These operators are used throughout Playwright assertions and API response processing — safely accessing response?.data?.items?.[0] without crashing on empty responses.

// EXAMPLE

const user = { profile: { score: 0 } };
const noUser = null;

// Optional chaining
console.log(user?.profile?.score);    // 0
console.log(noUser?.profile?.score);  // undefined (no TypeError)
console.log(user?.address?.city);     // undefined

// Nullish coalescing — preserves 0 and ''
console.log(user?.profile?.score ?? 100);  // 0  (not 100!)
console.log(0 ?? 100);                     // 0
console.log(0 || 100);                     // 100 (often a bug)
console.log('' ?? 'default');              // ''
console.log('' || 'default');              // 'default'

// API response in tests
const items = response?.data?.items ?? [];
const first = items[0]?.name ?? "unknown";

// WHAT INTERVIEWERS LOOK FOR

The key distinction: `??` vs `||` and why `??` is safer when 0 or empty string are valid values. The short-circuit behaviour of `?.`. Connecting to API response processing and test assertions.

// COMMON PITFALL

Using `||` where `??` is needed — `score || 0` replaces a genuine score of 0 with 0 (accidentally works), but `retries || 3` replaces a configured 0 retries with 3, silently breaking behaviour.