JavaScript Optional Chaining Operator (?.)

1. Introduction

The optional chaining operator (?.) enables you to read the property within a chain of connected objects without specifically checking each reference in the chain for null or undefined.

The ?. operator short-circuits the chain and returns undefined if any reference in the chain is nullish (null or undefined). The behavior of ?. operator is similar when used with function calls, it returns undefined if the function does not exists.

Let us now understand what problem does optional chaining (?.) operator solve.

let address = {};
let city = address.state.city; // TypeError, if state is null or undefined

You don’t want to get TypeError. You want to get undefined if the property is not there. The solution is to use the following code:

let address = {};
let city = address.state ? address.state.city : undefined;

This code doesn’t look clean as address.state comes twice in the code. This code becomes more complex if we want to get city code.

let address = {};
let cityCode = address.state ? address.state.city : address.state.city.cityCode : null : null;

You can use optional chaining to solve this problem:

let address = {};
let cityCode = address?.state?.city?.cityCode;  //undefined

JavaScript checks the left part of ?. to check if it is not null or undefined. If it is null or undefined, the right side of ?. is not accessed.

2. The variable before ?. must be declared

The optional chaining works with only declared variables. The variable before ?. must be declared either as let, const, var or as a function parameter. If it is not declared then ReferenceError is thrown.

let state = address?.city; //ReferenceError: address is not defined

3. Optional chaining with function calls

The optional chaining can be used with function calls similar to object properties. If you don’t know whether the function exists with the object, you can use optional chaining. Let us understand this with the help of an example.

let myObj = {};
myObj.myMethod();  //TypeError: myObj.myMethod is not a function

Since there is no myMethod in myObj, TypeError is thrown. The solution is to use optional chaining.

let myObj = {};
myObj.myMethod?.(); //TypeError: myObj.myMethod is not a function

Following are some important points to note:

  • If myMethod is a property, TypeError with message myObj.myMethod is not a function will be thrown.
  • myObj need to be declared, else ReferenceError is thrown.
  • If myObj is null or undefined, TypeError is thrown. You can use optional chaining to avoid this: myObj?.myMethod?.();

4. Optional chaining with bracket notation

Optional chaining can be used with bracket notation.


5. Can’t use optional chaining on the left-hand side of an assignment

We can use ?. for safe reading but not writing.

let object = {};
object?.property = 5; // SyntaxError: Invalid left-hand side in assignment

6. Access array items with optional chaining

Optional chaining can be used to safely read array items:

let arrItem = arr?.[10];

7. Optional chaining with delete

Also we can use ?. with delete:

delete address?.state; // delete address.state if address exists