100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
JavaScript

Optional Chaining and Nullish Coalescing

The ES2020 ?. and ?? operators for safely accessing nested properties and providing defaults only for null/undefined.

ES6+ FeaturesIntermediate9 min readJul 8, 2026
Analogies

1. Introduction

Accessing deeply nested properties on an object that might be missing pieces used to require verbose, error-prone guard checks like obj && obj.a && obj.a.b. ES2020 introduced two operators to solve this cleanly: optional chaining (?.), which safely accesses properties/methods that might not exist, and nullish coalescing (??), which provides a default value only when the left side is null or undefined, unlike || which also triggers on any falsy value.

🏏

Cricket analogy: Before ES2020, checking a scorecard's nested data meant writing "match && match.innings && match.innings.batsman" like manually verifying each level of a scoreboard exists before reading it; now "match?.innings?.batsman" does it safely, and "runs ?? 0" only defaults when runs is truly unrecorded, not when a batsman genuinely scored 0.

2. Syntax

javascript
// Optional chaining
const city = user?.address?.city;       // property access
const result = user?.getName?.();       // method call
const item = list?.[0];                 // bracket/array access

// Nullish coalescing
const port = config.port ?? 8080;       // fallback only for null/undefined

// Combining both
const theme = settings?.ui?.theme ?? 'light';

3. Explanation

Optional chaining (?.) checks whether the value immediately to its left is null or undefined. If it is, the entire expression short-circuits and evaluates to undefined without throwing, skipping any further property accesses or calls to the right. If the value is not nullish, evaluation continues as normal. This works for property access (?.prop), computed/bracket access (?.[expr]), and function calls (?.()), and it is essential for method calls where the method itself might not exist on the object.

🏏

Cricket analogy: "player?.stats?.average" checks if player exists before reading stats, short-circuiting to undefined instead of crashing if a substitute hasn't been named yet; "player?.celebrate?.()" is essential since not every player has a signature celebration method defined.

Nullish coalescing (??) returns its right-hand operand only when the left-hand operand is null or undefined. This is an important distinction from the logical OR operator ||, which returns the right-hand side for *any* falsy value, including 0, '', false, and NaN — values that are often perfectly valid, intentional data.

🏏

Cricket analogy: "oversBowled ?? 10" only kicks in if oversBowled was never recorded, correctly leaving a genuine 0-overs opening spell untouched, whereas "oversBowled || 10" would wrongly overwrite that legitimate 0.

Gotcha — ?? vs ||: const count = 0; const displayCount = count || 10; gives 10 (wrong, since 0 is a valid count), but const displayCount = count ?? 10; correctly gives 0. Use ?? whenever falsy-but-valid values like 0, '', or false should be preserved, and reserve || for when you genuinely want to replace any falsy value.

Gotcha — optional chaining short-circuits the WHOLE chain: const x = a?.b.c.d; — if a is null/undefined, the entire expression short-circuits to undefined immediately (b, c, d are never accessed, so no TypeError occurs), but note only a?.b is optional here; if a exists but a.b is null, accessing .c next would still throw, because the ?. was only placed once. Chain ?. at every level that might be missing: a?.b?.c?.d.

4. Example

javascript
const users = [
  { name: 'Ada', profile: { visits: 0, bio: null } },
  { name: 'Grace' }
];

for (const u of users) {
  const visits = u.profile?.visits ?? 'unknown';
  const bio = u.profile?.bio ?? 'No bio provided';
  const greet = u.sayHi?.() ?? 'no greeting method';
  console.log(u.name, '| visits:', visits, '| bio:', bio, '| greet:', greet);
}

5. Output

text
Ada | visits: 0 | bio: No bio provided | greet: no greeting method
Grace | visits: unknown | bio: No bio provided | greet: no greeting method

6. Key Takeaways

  • ?. safely accesses a property, index, or calls a method only if the preceding value is not null/undefined, otherwise it short-circuits to undefined.
  • ?. works for property access (?.prop), bracket access (?.[expr]), and function calls (?.()).
  • ?? returns the right-hand value only when the left-hand value is null or undefined.
  • Unlike ||, ?? preserves valid falsy values such as 0, '', and false instead of overriding them.
  • ?. must be applied at every level of a chain that might be missing, not just the first.
  • Combining ?. and ?? (e.g. a?.b?.c ?? 'default') is a common, readable pattern for safe defaults.

Practice what you learned

Was this page helpful?

Topics covered

#JavaScript#JavaScriptProgrammingStudyNotes#Programming#OptionalChainingAndNullishCoalescing#Optional#Chaining#Nullish#Coalescing#StudyNotes#SkillVeris