JavaScript Optional Chaining

Optional chaining is a new feature in JavaScript, introduced in ES2020, that allows you to safely access nested properties or methods without having to manually check if each property exists. This can help to simplify code and reduce the likelihood of errors due to undefined values.

Syntax

The Optional Chaining operator is spelled ?.. It may appear in three positions:

obj?.prop       // optional static property access
obj?.[expr]     // optional dynamic property access
func?.(...args) // optional function or method call

If the operand at the left-hand side of the ?. operator evaluates to undefined or null, the right-hand side will not be evaluated as short-circuiting, the expression evaluates to undefined. Otherwise the targeted property access, method or function call is triggered normally.

a?.[++x] // `x` is incremented if and only if `a` is not null/undefined

Optional chaining pairs well with nullish coalescing ?? to provide fallback values.

const data = obj?.prop ?? "fallback string"

Using with properties

const user = {
  name: 'John',
  address: {
    city: 'New York',
    state: 'NY'
  }
};

const city = user.address.city;
console.log(city); // 'New York'

In this example, we are accessing the city property of the address object nested within the user object. If the address object did not exist, this code would result in an error.

With optional chaining, we can safely access nested properties or methods without having to manually check if each property exists:

const user = {
  name: 'John'
};

const city = user.address?.city;
console.log(city); // undefined

In this example, we are using the ?. operator to access the city property of the address object. If the address object does not exist, the result will be undefined instead of an error.

Using with methods

const user = {
  name: 'John',
  getAddress() {
    return {
      city: 'New York',
      state: 'NY'
    };
  }
};

const city = user.getAddress()?.city;
console.log(city); // 'New York'

In this example, we are using the ?. operator to access the city property of the object returned by the getAddress method. If the getAddress method does not exist or returns undefined, the result will be undefined instead of an error.

Using with expressions

You can also use the optional chaining operator with bracket notation, which allows passing an expression as the property name. This is particularly useful for arrays:

const users = [
  { name: 'John', address: { city: 'New York', state: 'NY' } },
  { name: 'Jane' }
];

const city = users[0].address?.city;
console.log(city); // 'New York'

const city2 = users[1].address?.city;
console.log(city2); // undefined

In this example, we are using the ?. operator to access the city property of the address object of the first item in the users array. If the address object or the first item in the array does not exist, the result will be undefined instead of an error. Similarly, we are using optional chaining to safely access the city property of the address object of the second item in the users array, which does not exist.