Optional Chaining & Nullish Coalescing
Optional chaining ( ?. ) safely reads deeply nested values without crashing on missing data, and nullish coalescing ( ?? ) supplies a fallback only when a value is null or undefined .
Learn Optional Chaining & Nullish Coalescing in our free JavaScript course — an interactive lesson with runnable examples, a practice exercise and a quick…
Part of the free JavaScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Together they replace long a && a.b && a.b.c guards and buggy || defaults with two tiny, precise operators.
📚 Prerequisites: You should understand objects, arrays, and the idea of truthy and falsy values . These operators are all about handling null and undefined gracefully.
🔗 Real-World Analogy: Optional chaining is like a cautious tour guide :
Reading user.address.city throws if address is missing. Optional chaining fixes that: user.address?.city stops and returns undefined the moment a link in the chain is null or undefined . This short-circuiting is the whole point — it never even evaluates what comes after the missing piece.
Only place ?. where data might be missing. If you know user always exists, write user.address?.city — over-using ?. can hide real bugs.
The same idea works for methods and array indexing. Use obj.method?.() to call a method only if it exists — perfect for optional callbacks. Use arr?.[i] to index only when the array is actually there. If the thing isn't callable or indexable, you get undefined rather than a crash.
Note the syntax: for calls and indexes the ?. comes before the parentheses or brackets — fn?.() and arr?.[0] , not fn()?. .
Optional chaining gives you undefined when data is missing — and ?? turns that into a sensible default. The crucial difference from || : ?? only falls back for null and undefined , while || also falls back for 0 , "" , and false . That distinction prevents a very common bug. The ??= operator assigns a default only when the target is nullish.
Pairs beautifully: const city = user?.address?.city ?? "Unknown"; reads safely AND provides a clean default in a single, readable line.
Read city safely and fall back to "Unknown" if it's missing.
Predict the output before revealing the answer.
An empty string — ?? only replaces null / undefined , and "" is neither.
fallback — || falls back on any falsy value, and "" is falsy.
undefined — the chain short-circuits at the very first null .
Read deeply nested settings safely and apply sensible defaults that keep valid 0 values.
Up next: Essential Array Methods — find, some, every, flat, and the new immutable ones. 🧰
Practice quiz
What does optional chaining (?.) return when a link in the chain is null or undefined?
- null
- An error is thrown
- undefined
- false
Answer: undefined. ?. short-circuits and evaluates to undefined instead of throwing a 'cannot read property' error.
Given ghost = { name: 'Nobody' } (no address), what does ghost?.address?.city return?
- undefined
- null
- ''
- It throws
Answer: undefined. The chain short-circuits at the missing address and returns undefined safely.
What is the difference between ?? and ||?
- They are identical
- || falls back only for null/undefined
- ?? falls back for any falsy value
- ?? falls back only for null/undefined; || falls back for any falsy value
Answer: ?? falls back only for null/undefined; || falls back for any falsy value. ?? only replaces null/undefined, while || also replaces 0, '', and false.
What does const count = 0; count ?? 10 evaluate to?
- 10
- 0
- undefined
- null
Answer: 0. 0 is not null or undefined, so ?? keeps it, giving 0 (unlike || which would give 10).
What does '' ?? 'fallback' evaluate to?
- An empty string
- 'fallback'
- undefined
- null
Answer: An empty string. ?? only replaces null/undefined; an empty string is neither, so it is kept.
What does '' || 'fallback' evaluate to?
- An empty string
- undefined
- 'fallback'
- false
Answer: 'fallback'. || falls back on any falsy value, and '' is falsy, so it returns 'fallback'.
How do you safely call a method only if it exists?
- obj.method()?.
- obj.method?.()
- obj?.method()
- obj.method!.()
Answer: obj.method?.(). For optional calls, ?. comes before the parentheses: obj.method?.().
What does ??= do?
- Always reassigns the variable
- Compares two values
- Deletes the property
- Assigns the value only if the target is currently null or undefined
Answer: Assigns the value only if the target is currently null or undefined. Nullish assignment x ??= y sets y only when x is null or undefined.
What is the result of const o = null; o?.x?.y?
- null
- undefined
- An error
- 0
Answer: undefined. The chain short-circuits at the very first null and returns undefined.
Why can a?.b.c still throw even though it uses optional chaining?
- ?. doesn't work on objects
- It never throws
- If a.b is missing, the non-optional .c still throws — guard every link with a?.b?.c
- c must be a function
Answer: If a.b is missing, the non-optional .c still throws — guard every link with a?.b?.c. ?. only guards the link it is attached to; you must write a?.b?.c to guard every possibly-missing link.