🧩 1. What Is Optional Chaining?
Optional chaining (?.
) lets you safely access nested object properties
without causing an error if something in the chain is null
or undefined
.
👉 It returns undefined
instead of throwing an error.
🧱 The Problem (Without Optional Chaining)
const user = {};
console.log(user.profile.name); // ❌ TypeError: Cannot read properties of undefined
Here, user.profile
is undefined
,
so trying to access .name
crashes the code.
✅ The Solution (With Optional Chaining)
const user = {};
console.log(user.profile?.name); // ✅ undefined (no error)
If profile
doesn’t exist, the expression simply stops and returns undefined
.
🧠 2. Basic Syntax
object?.property
object?.[key]
object?.method?.()
You can use it with:
- Object properties
- Dynamic keys
- Methods/functions
🧩 Example 1 — Object Property
const user = { info: { name: "Alice" } };
console.log(user.info?.name); // "Alice"
console.log(user.profile?.name); // undefined (no error)
🧩 Example 2 — Array Index or Dynamic Key
const data = { items: ["A", "B"] };
console.log(data.items?.[0]); // "A"
console.log(data.other?.[0]); // undefined
🧩 Example 3 — Method Calls
const user = {
greet() {
return "Hello!";
},
};
console.log(user.greet?.()); // "Hello!"
console.log(user.sayBye?.()); // undefined (no crash)
🧩 Example 4 — Nested Access
Without optional chaining:
const city = user && user.address && user.address.city;
With optional chaining:
const city = user?.address?.city;
✅ Much cleaner and more readable.
⚡ 3. Combining with Nullish Coalescing (??
)
You can combine ?.
with ??
(another ES2020 feature)
to provide default values when something is missing.
const user = {};
const city = user?.address?.city ?? "Unknown";
console.log(city); // "Unknown"
✅ Returns "Unknown"
instead of crashing or showing undefined
.
🧩 4. Real-World Example
Example: API Response
const response = {
user: {
profile: { name: "Sarah" },
},
};
// Traditional way (unsafe)
console.log(response.user.profile.name); // Works
// console.log(response.account.details.id); // ❌ crash
// Safe way
console.log(response.account?.details?.id); // ✅ undefined
✅ Helps when working with APIs or user input where data may be missing.
🚨 5. What It Can’t Do
❌ You can’t use it on the left-hand side of an assignment:
user?.name = "Alice"; // SyntaxError ❌
❌ It only checks for null
or undefined
, not falsy values like 0
or ""
.
🧠 6. Quick Comparison
Without Optional Chaining | With Optional Chaining |
---|---|
user && user.address && user.address.city | user?.address?.city |
data && data.items && data.items[0] | data?.items?.[0] |
obj && obj.method && obj.method() | obj.method?.() |
✨ 7. Summary
Concept | Description | Example | Result |
---|---|---|---|
?. | Safe property access | user?.name | Returns undefined if missing |
?.[] | Safe dynamic key access | user?.[key] | Returns undefined if missing |
?.() | Safe method call | user.method?.() | Calls only if method exists |
💡 8. Practical Tip
Optional chaining is best for:
- API responses with optional fields
- Deeply nested data (e.g.,
user?.profile?.settings?.theme
) - Avoiding repetitive
if
or&&
checks