← Back to Chapters

JavaScript Optional Chaining

? JavaScript Optional Chaining

⚡ Quick Overview

Optional chaining (?.) lets you safely access deeply nested object properties, methods, or array elements without throwing an error if something in the chain is null or undefined. Instead of a runtime error, the expression evaluates to undefined.

It is especially useful when working with API responses or complex objects where some properties might be missing.

? Key Concepts

  • Safe property access: Use obj?.prop to access a property only if the object exists.
  • Safe nested access: Use obj?.nested?.prop to avoid long chains of checks.
  • Safe method calls: Use obj.method?.() to call a method only if it exists.
  • Safe array indexing: Use arr?.[index] to access an element only if the array exists.
  • Short-circuiting: As soon as a null or undefined is found in the chain, the whole expression returns undefined.

? Syntax and Usage

  • obj?.prop – safely access prop of obj.
  • obj?.[expr] – safely access a dynamic property using an expression.
  • obj.method?.() – safely call method() if it exists.

Optional chaining is read-only – it does not create properties or modify objects. It only affects how JavaScript reads values from them.

? Code Examples

? Basic Object Property Access

? View Code Example
const user = {
name: 'Alice',
address: { city: 'London' }
};

Accessing existing property → 'Alice'
console.log(user?.name);

Accessing nested property safely → 'London'
console.log(user?.address?.city);

Accessing non-existent property → undefined (no error)
console.log(user?.contact?.email);

? Optional Chaining with Functions

? View Code Example
const user = {
name: 'Bob',
greet: () => 'Hello!'
};

Call greet only if it exists
console.log(user.greet?.());

sayBye does not exist → returns undefined, no error
console.log(user.sayBye?.());

? Optional Chaining with Arrays

? View Code Example
const users = [
{ name: 'Sam' },
{ name: 'Lara' }
];

Valid index → 'Sam'
console.log(users?.[0]?.name);

Out-of-range index → undefined (no error)
console.log(users?.[5]?.name);

const response = null;
Safely reading deeply nested data from a nullable response
console.log(response?.data?.items?.[0]);

? Combining Optional Chaining with Nullish Coalescing

? View Code Example
const settings = {
theme: {
color: 'dark'
}
};

If theme or color is missing, use 'light' as default
const themeColor = settings?.theme?.color ?? 'light';
console.log(themeColor);

? Live Output and Explanation

In the basic example:

  • user?.name returns 'Alice' because user exists and has name.
  • user?.address?.city returns 'London' because both address and city exist.
  • user?.contact?.email returns undefined because contact is undefined, but no error is thrown.

In the function example, user.greet?.() calls the function and returns 'Hello!', while user.sayBye?.() simply evaluates to undefined because sayBye is not defined.

With arrays, users?.[5]?.name is safe even though index 5 does not exist. Without optional chaining, directly accessing users[5].name would cause a runtime error.

? Tips and Best Practices

  • Combine optional chaining with nullish coalescing (??) to provide safe default values.
  • Use optional chaining instead of many nested if checks to keep your code clean and readable.
  • Great for working with uncertain data (e.g., API responses where some fields may be missing).
  • Do not overuse it – for required fields, validate data explicitly instead of silently returning undefined.
  • Remember: optional chaining is for reading values, not for assigning or creating new ones.

? Try It Yourself

  • Create an object that represents an API response (e.g., user.profile.settings) and safely access a deeply nested property using optional chaining.
  • Add an optional method (e.g., onLogin) to an object. Call it using obj.onLogin?.() and provide a fallback message using ??.
  • Declare an array of users and safely access different indices with arr?.[index]?.name, including out-of-range indices.
  • Experiment by removing some properties from your objects and observe how optional chaining prevents errors.