Optional chaining in JavaScript: reading a property without crashing the page

Optional chaining stops reading a property chain as soon as a value is empty, returning undefined instead of throwing an error.
3 min read
Believemy logo

Data comes back from an API, three properties get read in a row, and the page goes blank. The message is always the same: cannot read properties of undefined. A well-placed question mark fixes it.


Definition

Optional chaining, written as a question mark followed by a dot, reads a property only when the value on its left is neither null nor undefined. Otherwise it stops evaluating right there and returns undefined.

JAVASCRIPT
const client = { profile: { city: "Lyon" } };

console.log(client.profile.city);   // "Lyon"
console.log(client.account?.iban);  // undefined, no error

// Without the operator, the line above would throw:
// TypeError: Cannot read properties of undefined

Everything hangs on the word stop. As soon as an empty value shows up, the rest of the chain is skipped, even if five levels remain. That behavior is called short-circuiting.


Three forms, not one

The operator is not limited to named properties. It has variants for indexes and for function calls, which many people never discover.

FormWhat it protects
object?.propertyReading a property
array?.[0]Access by index or computed key
fn?.()The call, when the function is missing

The third form genuinely helps with optional callbacks: onSuccess?.() calls the function when one was supplied, and does nothing otherwise. No need to wrap the call in a condition anymore.

Good to know

The operator only works for reading. An assignment such as object?.field = 1 is rejected by the engine with a syntax error. To write, you first have to guarantee that the object exists.


What it does not do

This is the most misunderstood point, and the one producing the quietest bugs. The operator guards against an empty value, not against a typo.

JAVASCRIPT
const client = { profile: { city: "Lyon" } };

console.log(client.profle?.city); // undefined, and no warning

The property is misspelled, the chain returns undefined, and the program carries on as if nothing happened. Without the operator, the same typo would have thrown immediately, and therefore visibly. By adding a question mark, you trade a loud crash for a silently wrong result.

The practical rule: use it only where emptiness is a normal, expected case. On data that must always be there, let the error happen.


Frequently asked questions

Question

Is a question mark needed at every level?

No, one is enough at the spot where emptiness is possible. Since evaluation stops at the first empty link, writing a?.b?.c?.d when only b can be missing adds weight without adding safety. Put the operator on the uncertain link, not across the whole chain.


Question

How do I attach a fallback value to it?

With Nullish coalescing (??), its natural companion. Writing client.profile?.city ?? "not provided" covers both needs: the read never crashes, and an absence produces something displayable rather than a visible undefined.


Question

Does it slow execution down?

No, the impact is negligible, and it is sometimes positive since evaluation stops earlier. The real cost lies elsewhere: on deeply nested outside data, it hides structural problems. Our Node.js course shows how to validate an API response on arrival, which beats guarding every single read.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.