The '?.' operator lets you safely read deeply nested properties without a chain of manual null checks. It's one of the highest-impact additions to modern JavaScript for working with real-world, unpredictable API data.
1Optional Chaining | JavaScript Tutorial - In-Depth Guide Part 1
Optional chaining ('?.') reads a property and short-circuits to 'undefined' instead of throwing if anything before it is null or undefined.
const city = user?.address?.city;Safe Access
2Optional Chaining | JavaScript Tutorial - In-Depth Guide Part 2
'?.' also works on array indices and function calls, not just object properties.
const first = list?.[0];
callback?.();Arrays & Calls
3Optional Chaining | JavaScript Tutorial - In-Depth Guide Part 3
Once the chain hits null or undefined, it short-circuits immediately — the rest of the expression never even evaluates.
user?.getProfile()?.avatarUrl;
// getProfile() never runs if user is nullShort-Circuiting
4Optional Chaining | JavaScript Tutorial - In-Depth Guide Part 4
Optional chaining only guards against null/undefined — it does not swallow other kinds of errors, like calling a non-function.
const obj = { name: 'x' };
obj.getName?.(); // TypeError if getName isn't callable...
// actually returns undefined only if getName itself is null/undefinedNot a Silver Bullet
5Optional Chaining | JavaScript Tutorial - In-Depth Guide Part 5
Optional chaining pairs naturally with nullish coalescing to supply a real default value once the chain bottoms out.
const city = user?.address?.city ?? 'Unknown';Pairs with ??
6Step-by-Step Breakdown
Optional chaining ('?.') reads a property and short-circuits to 'undefined' instead of throwing if anything before it is null or undefined.
'?.' also works on array indices and function calls, not just object properties.
Checkpoint: Does callback?.() throw an error if callback is undefined?
- →Yes, calling undefined always throws
- →No, it short-circuits to undefined instead
Once the chain hits null or undefined, it short-circuits immediately — the rest of the expression never even evaluates.
Optional chaining only guards against null/undefined — it does not swallow other kinds of errors, like calling a non-function.
Checkpoint: Does optional chaining protect against calling a property that exists but is not actually a function?
- →Yes, it safely handles any call
- →No, it only guards against null/undefined links
Optional chaining pairs naturally with nullish coalescing to supply a real default value once the chain bottoms out.
Next, we'll explore 'Nullish Coalescing'.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Guard Optional Data Before Building ARIA Attributes
When an ARIA attribute value depends on optional nested data (e.g. `aria-label={item?.accessibility?.label}`), pair the chain with a sensible fallback string so assistive technology never receives an empty or undefined label.
SEO Implications
- 1
Fewer Runtime Crashes Means More Reliably Rendered Pages
A single uncaught TypeError from a missing nested property can crash an entire server-rendered page in some frameworks; optional chaining reduces that risk, keeping content consistently crawlable.
Best Practices
Use Optional Chaining for Genuinely Optional Data
Reach for `?.` when a property is legitimately allowed to be missing (like an optional API field); don't scatter it everywhere as a substitute for proper validation, since it can silently hide real bugs.
Combine `?.` with `??` for Display Defaults
Chaining alone yields `undefined`, which is rarely what you want to render — pairing it with nullish coalescing gives you a safe access path *and* a sensible fallback value in one expression.
Frequent Bugs
Sprinkling `?.` everywhere on data that should never actually be missing masks a real upstream bug (like a broken API contract) by silently producing undefined instead of surfacing an error.
Reserve optional chaining for properties that are legitimately optional per your data contract; validate or throw explicitly for data that should always be present.
Using `user?.age || 0` to default a numeric field incorrectly replaces a legitimate `0` age with the fallback, since `0` is falsy.
Use nullish coalescing (`user?.age ?? 0`) instead of `||`, since `??` only falls back on null/undefined, not on other falsy values like 0 or an empty string.
Real-World Examples
Safely Rendering an Optional Nested API Field
A product card needed to display a manufacturer's support phone number, which was only present for some products in a deeply nested API response.
const supportPhone = product?.manufacturer?.contact?.phone ?? 'Not available';