Optional Chaining (?.) & Nullish Coalescing (??)
Optional chaining (?.) safely accesses nested properties without crashing on null/undefined. Nullish coalescing (??) provides defaults only for null/undefined (not 0 or ''). Both prevent common crashes in real-world code.
?. and ??
- Optional chaining (?.) — user?.address?.city; returns undefined (not Error) if user is null/undefined
- Works with methods — user?.greet?.(); calls greet only if it exists
- Works with arrays — users?.[0]?.name; safe array access
- Nullish coalescing (??) — value ?? default; default ONLY if value is null/undefined
- ?? vs || — || treats 0, '', false as falsy. ?? only treats null/undefined as 'missing'
- Combine — user?.name ?? 'Guest'; safe access + safe default
Optional Chaining & Nullish Coalescing Code
// Without optional chaining — bug-prone
const user = null;
// console.log(user.name); // ❌ TypeError: Cannot read property 'name' of null
// console.log(user.address.city); // ❌ Crash!
// ✅ With optional chaining
console.log(user?.name); // undefined (no crash!)
console.log(user?.address?.city); // undefined
// Nested access
const profile = {
name: "Alice",
settings: {
theme: "dark",
notifications: { email: true }
}
};
console.log(profile?.settings?.theme); // "dark"
console.log(profile?.settings?.notifications?.sms); // undefined
console.log(profile?.nonexistent?.deep?.value); // undefined
// Optional method calls
const obj = { greet: () => "Hello!" };
console.log(obj.greet?.()); // "Hello!"
console.log(obj.farewell?.()); // undefined (no crash)
// Nullish coalescing (??) vs OR (||)
const port = 0;
console.log(port || 3000); // 3000 ← WRONG! 0 is valid
console.log(port ?? 3000); // 0 ← CORRECT! 0 is not null/undefined
const name = "";
console.log(name || "Guest"); // "Guest" ← maybe wrong (empty string is intentional?)
console.log(name ?? "Guest"); // "" ← keeps empty string
const value = null;
console.log(value ?? "default"); // "default" ← null triggers ??
// Combined pattern
const config = null;
const theme = config?.settings?.theme ?? "light";
console.log(theme); // "light" (safe access + safe default)Tip
Tip
Use ?? for values where 0 or '' are valid: const port = config.port ?? 3000. Use || when any falsy value should trigger the default. Use ?. to safely navigate nested properties: user?.profile?.avatar.
?? only checks null/undefined, || checks all falsy.
Common Mistake
Warning
Using || instead of ?? when 0 or empty string are valid values. const count = input || 10 replaces 0 with 10, which is usually wrong. const count = input ?? 10 only replaces null/undefined. Know the difference.
Practice Task
Note
Practice modern operators: (1) Use ?. to safely access nested API response properties. (2) Use ?? vs || on values like 0, '', and false to see the difference. (3) Use ??= to set defaults on an object's properties.
Quick Quiz
Key Takeaways
- Optional chaining (.
- Optional chaining (?.) — user?.address?.city; returns undefined (not Error) if user is null/undefined
- Works with methods — user?.greet?.(); calls greet only if it exists
- Works with arrays — users?.[0]?.name; safe array access