Day 3 · Concept 09
Optional chaining & nullish coalescing
foo?.bar?.baz short-circuits if any link is null/undefined. x ?? defaultValue picks the default only when x is null/undefined — not when x is 0 or "".
1 · The old way
const data = { user: { profile: null } };
// Before optional chaining
const handle = data && data.user && data.user.profile && data.user.profile.handle;
console.log(handle); // undefined
// Or with try/catch — even uglier
let h;
try { h = data.user.profile.handle; } catch { h = undefined; }
console.log(h);2 · The modern way — ?.
const data = { user: { profile: null } };
// Optional chaining
const handle = data?.user?.profile?.handle;
console.log(handle); // undefined
// On method calls too
const onChange = obj?.callback?.(); // calls only if callback exists
// On array access
const first = arr?.[0];The chain returns undefined at the first null/undefined link. No exceptions thrown.
3 · Nullish coalescing — ??
// || picks the right side for ANY falsy value — wrong for 0 / "" / false
console.log(0 || 10); // 10 (probably not what you wanted!)
console.log("" || "default"); // 'default'
console.log(false || true); // true
// ?? picks the right side ONLY for null / undefined
console.log(0 ?? 10); // 0 ✓
console.log("" ?? "default"); // '' ✓
console.log(null ?? "fallback"); // 'fallback'
console.log(undefined ?? 42); // 424 · The combo
function getDisplay(user) {
return user?.profile?.displayName ?? "Anonymous";
}
console.log(getDisplay({})); // Anonymous
console.log(getDisplay({ profile: { displayName: "Alice" } })); // Alice
console.log(getDisplay(null)); // AnonymousReach into a possibly-missing path; fall back to a default. The most common modern pattern.
5 · Common mistakes
- Using
||when you meant??.const max = config.max || 100— ifconfig.maxis 0, you get 100. Use??. - Optional chaining on the LHS of assignment.
obj?.x = 1is a syntax error. Use a guard. - Forgetting
?.()for methods.obj?.fn()only short-circuits the?.; ifobjis null,fn()doesn't run.
6 · When it clicks
?.and??are reflex moves on any optional data.- You stop writing
&&-chain guards. - You notice
||bugs in code reviews — empty strings or zeros silently replaced.
Found this useful?