Optional Chaining β Safely Accessing with the ?. Operator
After completing this topic, you will:
Understand why and how the ?. operator works, and in what real-world scenarios it can be used.
The Pitfall of Nested Objects
You have user data fetched from an API:
const user = {
name: "Alice",
address: {
city: "Seoul"
}
};
console.log(user.address.city); // "Seoul"However, some users haven't entered their address:
const user = { name: "Bob" };
console.log(user.address.city);
// TypeError: Cannot read properties of undefinedBecause user.address is undefined, attempting to read .city from it results in an error. This is one of the most common runtime errors in JavaScript.
The Old Way: Chained if Statements
let city;
if (user && user.address && user.address.city) {
city = user.address.city;
}You have to check each intermediate step. The code becomes longer as the nesting gets deeper.
Optional Chaining: ?.
const city = user?.address?.city;The ?. operator returns undefined without throwing an error if the value on the left is null or undefined.
user?.address?.city can be read as follows:
- If
userexists, proceed to.address. - If
addressexists, proceed to.city. - If
nullorundefinedis encountered at any point, immediately returnundefined.
This allows you to safely access properties in a single line.
Also Works with Methods and Arrays
It can also be used when calling methods:
const result = user.getProfile?.();If getProfile exists, it is called; otherwise, undefined is returned. The ?. is placed before the parentheses.
It also works for accessing array indices:
const first = users?.[0]?.name;No error will occur even if the users array does not exist or is empty.
Combining with Nullish Coalescing (??)
The nullish coalescing operator ?? is often used in conjunction with ?.:
const city = user?.address?.city ?? "Unknown";Safely access with ?., and if the result is null or undefined, use the default value after ??. Unlike ||, it treats 0 or "" (empty string) as valid values.
const count = data?.total ?? 0; // If total is 0, keep it as 0
const count2 = data?.total || 0; // total being 0 also makes it falsy, so it returns 0 (may not be the intended behavior)Be Careful Not to Overuse
Just because ?. is convenient doesn't mean you should use it everywhere:
// This is excessive
const name = user?.name?.toString?.()?.trim?.();If user.name is guaranteed to exist, it is better to access it without ?.. You should be able to catch bugs by having errors occur.
?. conveys the meaning that "this value may not exist" in the code. Use it only in places where it really might not exist.
Key Takeaways
?.returnsundefinedinstead of an error when it encountersnull/undefined. Use it when accessing data with uncertain structure, such as API responses. Combining it with??allows you to handle default values cleanly.