Optional chaining: ‘?.’
The optional chaining ?.
is a safe way to access nested object properties, even if an intermediate property doesn’t exist or you can say “non-existing property” problem.
If a case, when we attempt to get user.address.street
, and the user happens to be without an address, we get an error:
let user = {}; // a user without "address" propertyalert(user.address.street); // Error!
That’s the expected result. JavaScript works like this. As user.address
is undefined
, an attempt to get user.address.street
fails with an error.
The obvious solution would be to check the value using if
or the conditional operator ?
, before accessing its property, like this:
let user = {};alert(user.address ? user.address.street ? user.address.street.name : null : null);
That’s just awful, one may even have problems understanding such code.
Don’t even care to, as there’s a better way to write it, using the &&
operator:
let user = {}; // user has no addressalert( user.address && user.address.street && user.address.street.name ); // undefined (no error)
AND’ing the whole path to the property ensures that all components exist (if not, the evaluation stops), but also isn’t ideal.
As you can see, property names are still duplicated in the code. E.g. in the code above, user.address
appears three times.
That’s why the optional chaining ?.
was added to the language. To solve this problem once and for all!
Optional chaining
The optional chaining ?.
stops the evaluation if the part before ?.
is undefined
or null
and returns that part.
In other words, value?.prop
:
- is the same as
value.prop
ifvalue
exists, - otherwise (when
value
isundefined/null
) it returnsundefined
.
let user = {}; // user has no address
alert( user?.address?.street ); // undefined (no error)
The code is short and clean, there’s no duplication at all.
If there’s no variable user
at all, then user?.anything
triggers an error:
// ReferenceError: user is not defined
user?.address;
The variable must be declared (e.g. let/const/var user
or as a function parameter). The optional chaining works only for declared variables.
Summary
The optional chaining ?.
syntax has three forms:
obj?.prop
– returnsobj.prop
ifobj
exists, otherwiseundefined
.obj?.[prop]
– returnsobj[prop]
ifobj
exists, otherwiseundefined
.obj.method?.()
– callsobj.method()
ifobj.method
exists, otherwise returnsundefined
.
A chain of ?.
allows to safely access nested properties.
Still, we should apply ?.
carefully, only where it’s acceptable that the left part doesn’t exist. So that it won’t hide programming errors from us if they occur.