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 messagemyObj.myMethod is not a function
will be thrown. myObj
need to be declared, elseReferenceError
is thrown.- If
myObj
isnull
orundefined
,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.
object?.["property"];
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