Because in Javascript objects can be very complex and have unpredictable structures, sometimes is hard to access their properties. There's a real possibility that some nested objects or properties might not exist so when trying to use them, we run into errors. Optional chaining
, as a part of ES2020
, changes and simplifies the way properties are accessed from deep objects structures. It is also available in TypeScript, starting from version 3.7
.
The
optional chaining operator
(?.) permits reading the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid. The?.
operator functions similarly to the . chaining operator, except that instead of causing an error if a reference is nullish (null or undefined), the expression short-circuits with a return value of undefined. When used with function calls, it returns undefined if the given function does not exist.
Without the optional chaining operator
, if we want to check for properties inside a deeply nested object, for example, we would need to first check if every reference exists, otherwise we risk getting into errors.
let person = {
name: "Ben",
age: 35,
bankDetails: {
IBAN: 781265489634,
accountNumber: 5689245522221
}
}
console.log(person.hobbies.fishing); // Uncaught TypeError: Cannot read property 'sum' of undefined
We get an error because we are trying to read the fishing
property on the hobbies
object but the person
object has no such nested object inside it. A workaround for this would be to write the code like so, using the &&
operator:
let person = {
name: "Ben",
age: 35,
bankDetails: {
IBAN: 781265489634,
accountNumber: 5689245522221
}
}
console.log(person && person.hobbies && person.hobbies.fishing); // undefined
The property still doesn't exist, but instead of a TypeError exception we not get back "undefined". Adding the &&
operator makes sure that all properties we're trying to check exist but it seems like a lot of work to always write it and it's hard to read too.
This is how the same code looks like with the chaining operator
.
let person = {
name: "Ben",
age: 35,
bankDetails: {
IBAN: 781265489634,
accountNumber: 5689245522221
}
}
console.log(person?.hobbies?.fishing);// undefined
The code looks much shorter and cleaner. The way the optional chaining operator
works is that it stops the evaluation and returns undefined
if the part before ?.
is null
or undefined
.
A small warning: not all browsers support this operator so make sure you don't need to use polyfills to avoid issues. You can check the compatibility here.
Image source: Startup Stock Photos/ @startup-stock-photos on Pexels
Top comments (12)
As far as I know, this is available even in ES2015, is it not?
It's not, it's part of the ES2020 :)
freecodecamp.org/news/javascript-n...
developer.mozilla.org/en-US/docs/W...
I saw it here and since it’s documented here, assumed it’s already present. I see the document was updated only recently and the cross browser stability has still not kicked in.
However I was able to use this in Typescript with es6 build (babel with backward compatibility) atleast 6-8 months back. Queer!
Usually when I read "ES6 build" it means it transpiles to ES6 code, rather than that it is already ES6 compatible. This operator, fortunately, is super easy to transpile back to older syntax, so Typescript has supported it (and the nullish coalescing operator) for a little while now
(Edit for tone, and to add some details)
This puts a lot of things into perspective! :) Thank you!
To be honest, it seemed familiar to me too but now I realize I must know it from Typescript.
Right yes! This must have been typescript and not JS :) anyways, a good list!
Nice feature and post!
Thx :)!
Nice to see this in JS! ☕
This.. this can becone usefull, tanks
Hope it helped :).