Optional Chaining

In the previous lesson, we learned how to provide safe defaults. Now let’s learn how to safely read values from objects that might not exist, using optional chaining.

🔗 What is Optional Chaining?

The optional chaining operator ?. lets you read a property deep inside an object without causing an error if part of the path is null or undefined. Instead of crashing, it simply returns undefined.

This solves one of the most common errors beginners hit: “Cannot read property of undefined”.

💥 The Problem It Solves

Imagine a user object where the address is sometimes missing.

optional-chaining.js
const user = {
name: "Alex",
};
console.log(user.address.city); // ❌ Error: Cannot read property 'city' of undefined

Let’s walk through why this code crashes:

  • The user object only has a name, so user.address is undefined.
  • Reading .city from undefined is not allowed, so JavaScript throws an error and stops the program.

✅ The Solution With ?.

With optional chaining, JavaScript checks each step. If address is missing, it stops and returns undefined instead of throwing an error.

optional-chaining.js
const user = {
name: "Alex",
};
console.log(user.address?.city); // undefined → no error

Here is what each part does:

  • The ?. after address says “only continue if the value before me exists”.
  • Since address is missing, JavaScript stops there and the whole expression becomes undefined, so nothing crashes.

🎯 Combining With Nullish Coalescing

Optional chaining pairs perfectly with the ?? operator from the last lesson. Use ?. to read safely, then ?? to provide a default.

optional-chaining.js
const user = {
name: "Alex",
};
const city = user.address?.city ?? "Unknown";
console.log(city); // "Unknown"

Let’s read this line from left to right:

  • user.address?.city safely reads the city and gives back undefined because address is missing.
  • The ?? operator then sees that undefined and replaces it with the fallback "Unknown".
  • So city ends up holding "Unknown", which we print.

A powerful pair

?. keeps your code from crashing, and ?? gives a sensible fallback. Together they make reading uncertain data safe and clean.

📞 Optional Chaining With Functions and Arrays

You can also use ?. to call a method that might not exist, or to read an array item safely.

optional-chaining.js
const user = {
name: "Alex",
};
// Call sayHi only if it exists
user.sayHi?.(); // does nothing, no error
// Read an array item safely
console.log(user.friends?.[0]); // undefined, no error

Let’s go through both safe operations:

  • user.sayHi?.() checks whether sayHi is a real function first; since it is missing, the call is skipped instead of throwing an error.
  • user.friends?.[0] checks whether friends exists before reading index 0; since it is missing, the expression returns undefined.
  • Notice the syntax: we write ?.() to call a function and ?.[0] to read an array item.

⚠️ Common Mistakes to Avoid

Mistake Problem Solution
Using ?. everywhere It can hide real bugs by silencing errors Use it only where a value is genuinely optional
Forgetting the default You get undefined instead of a useful value Add ?? defaultValue when you need a fallback
Wrong syntax for arrays or calls user.friends?.0 is invalid Use ?.[0] for arrays and ?.() for function calls

🔧 Try It Yourself!

  1. Create a user object with only a name property.
  2. Try reading user.address.city and see the error.
  3. Use user.address?.city and see it return undefined instead.
  4. Add ?? "Unknown" to provide a default value.

🧩 What You’ve Learned

  • ?. safely reads properties that might not exist
  • ✅ It returns undefined instead of throwing an error
  • ✅ It prevents the common “Cannot read property of undefined” crash
  • ✅ Combine ?. with ?? to read safely and provide a default
  • ✅ Use ?.() for optional function calls and ?.[index] for arrays

🚀 What’s Next?

You have finished the Operators module. Next, we will start controlling which code runs using conditions, beginning with the if statement. Let’s continue to if Statement.

Share & Connect