Optional chaining operator
Optional chaining (?.) is a modern operator (ES2020) that lets you safely access object properties even when part of the chain is undefined or null. Instead of a long run of guards you write a single symbol and get undefined where you used to get a TypeError.
Theory
TL;DR
?.short-circuits the chain as soon as the left side isnullorundefinedand returnsundefined.- Three forms: property access
obj?.prop, method callobj.method?.(), index accessarr?.[0]. - The equivalent under the hood:
obj == null ? undefined : obj.prop. - It checks only for
nullandundefined, not for "empty" values like0,''orfalse. - It pairs nicely with
??for a default value. - It cannot be placed on the left-hand side of an assignment.
Quick example
const user = {
profile: {
name: 'Alice'
}
};
console.log(user.profile?.name); // "Alice"
console.log(user.address?.city); // undefined (no error)The problem without optional chaining
Suppose we have a nested object:
const user = {
profile: {
name: 'Alice'
}
};If we try to reach a field that does not exist:
console.log(user.address.city); // TypeError: Cannot read properties of undefinedThe error happens because
user.addressisundefined, and trying to readundefined.citybreaks the code.
The solution, the ?. operator:
console.log(user.address?.city); // undefined (no error)If the value before ?. exists, the property is returned. If it is undefined or null, the result is undefined and the program does not crash.
Forms of the syntax
1. Property access
user?.profile?.name // "Alice"
user?.address?.city // undefined2. Method access
user.sayHi?.(); // calls the method if it exists3. Array element access
const arr = null;
console.log(arr?.[0]); // undefined (no error)An example with API data
const response = {
user: { name: 'Alice', address: null }
};
console.log(response.user?.address?.city); // undefinedWithout ?. you would have to write long guards:
response && response.user && response.user.address && response.user.address.cityOptional chaining with nullish coalescing
These two operators are often used together:
const city = user.address?.city ?? 'Not specified';
console.log(city); // "Not specified"?.accesses the property safely.??supplies a default value when the result isundefinedornull.
Unlike ||, the ?? operator does not replace valid falsy values: 0 ?? 10 gives 0, while 0 || 10 gives 10.
What it does under the hood
obj?.prop
// equivalent to:
obj == null ? undefined : obj.propThe loose comparison == null is true for both null and undefined, so one operator covers both cases. An important detail: the chain short-circuits, so in a?.b.c the rest of the expression is not evaluated at all when a is null.
Where you can use it
| Situation | Example | Result |
|---|---|---|
| Object property | user?.name | 'Alice' or undefined |
| Nested objects | user?.address?.city | safe |
| Method call | user.method?.() | called if the method exists |
| Array element | arr?.[0] | the first element or undefined |
Where you cannot use it
// not allowed on the left of an assignment
user?.name = 'Alex'; // SyntaxError
// not an existence check: it yields undefined, not false
if (user?.missing) { /* ... */ }Summary table
| What it does | How it works |
|---|---|
Optional chaining (?.) | Accesses a property safely without throwing |
| Returns | undefined when it meets null or undefined |
| Used for | accessing nested properties, methods and elements |
| Combined with | ?? most of the time, for default values |
Common mistakes
- Putting
?.in every link "just in case". It masks real bugs: ifuseralways exists by contract,user?.profileonly hides a data problem. - Confusing it with an "empty value" check.
?.reacts only tonullandundefined;0,''andfalsepass through as ordinary values. - Combining
??with||or&&without parentheses.a ?? b || cis aSyntaxError, explicit parentheses are required. - Forgetting that the chain can still throw after a
?.. Inuser?.address.cityonlyuseris guarded; ifaddressisundefined, you get aTypeError. - Calling a method as
user?.sayHi()instead ofuser.sayHi?.(). The first form only guards against a missinguser, not against a missing method. - Using
?.on the left of an assignment. That is a syntax error, the operator is read-only.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.