Compile Ready
Module 10 · ES6+ Features

Optional Chaining

Intermediate9m read7m practice16m total
Optional ChainingES2020Null SafetyObjects

Introduction

Optional chaining (?.) safely reads a property, calls a method, or indexes a value only when the value to its left is not null or undefined. If the left side is nullish, the whole optional chain short-circuits to undefined.

It is not a replacement for validation; it is a concise way to express "continue only if this object exists".

Why This Matters

Real applications consume incomplete data: API responses, feature flags, optional callbacks, and configuration objects. Optional chaining prevents defensive code from turning into nested if statements while preserving the important distinction between missing data and falsy-but-valid data.

Theory

Forms of optional chaining

  • Property access: user?.profile.
  • Element access: rows?.[0].
  • Optional call: onSuccess?.(result).

The operator checks only the value immediately to its left. In user?.profile.name, user is protected, but profile.name is not optional. Use user?.profile?.name if both levels may be missing.

Short-circuiting

When optional chaining short-circuits, later property lookups, index expressions, and call arguments in that chain are not evaluated. This matters for side effects such as counters or function calls inside arguments.

Result is undefined

The fallback result is always undefined, not null. Combine optional chaining with nullish coalescing when you need a default: user?.profile?.city ?? 'Unknown'.

Limits

Optional chaining cannot be used on the left side of assignment (user?.name = 'Ada' is invalid). It also does not catch errors thrown by an existing getter or method; it only avoids accessing through null or undefined.

Visual Diagrams

Optional chain decision path
user?.profile?.city
  |
  +-- user is null or undefined? yes -> undefined
  |
  no
  v
profile is null or undefined? yes -> undefined
  |
  no
  v
read city

Each optional hop guards only the value immediately before it.

Code Examples

Property, element, and call forms

Optional chaining is available for the three access patterns you use most often.

Loading…

Pairing with nullish coalescing

Optional chaining returns undefined; ?? provides a default only for nullish results.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1let calls = 0;
2const user = null;
3
4const result = user?.profile?.getCity(calls++);
5
6console.log(result);
7console.log(calls);

Predict the output #2

javascript
1const user = {
2 profile: {
3 getName: function () {
4 return 'Ada';
5 }
6 }
7};
8
9console.log(user?.profile?.getName?.());
10console.log(user?.settings?.theme ?? 'light');

Coding Exercises

Read a safe profile summary

Easy

Implement profileSummary(user) so it returns { name, city, company }. Use optional chaining and nullish coalescing so missing values become 'Unknown', but an empty string is preserved.

Interview Questions

1What exactly does optional chaining guard against?

It guards against the value immediately to its left being null or undefined. If that value is nullish, the chain returns undefined. It does not guard against other falsy values, and it does not suppress errors thrown by existing getters or methods.

Asked at:AmazonMeta
2Why might `user?.profile.name` still throw?

Only user is optional in that expression. If user exists but profile is undefined, then .name is attempted on undefined and throws. Use user?.profile?.name when both levels are optional.

Follow-ups

  • How does optional call syntax work?
  • What value does an optional chain produce when it short-circuits?

Quiz

1. What is the result of `null?.x`?

2. Which expression safely calls `onDone` only if it exists?

Summary

  • Optional chaining guards property access, element access, and function calls against `null` and `undefined`.
  • Each `?.` protects only the value immediately to its left.
  • A short-circuited optional chain returns `undefined` and skips later side effects in the chain.
  • Combine `?.` with `??` to provide defaults without replacing valid falsy values.

Cheat Sheet

Property: obj?.prop.

Element: arr?.[index].

Call: callback?.(value).

Nested: use ?. at every uncertain level: user?.profile?.city.

Default: user?.profile?.city ?? 'Unknown'.