It is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.
let's see some use-cases that you might encounter frequently, where the ( ?? ) operator can make your life easier :)
(Code snippet—1.1)
The most common use-case is accessing a value from a nested Object in javascript.
In Code snippet—1.1 you can see that we are trying to access the key ‘name’ from the data object, which is a nested object, and it gives us the expected result.
(Code snippet—1.2)
In Code snippet—1.2 you can see that now the nested data object doesn't contain the ‘name’ key. And when we try to access the ‘name’ key from it, we get undefined.
Getting an undefined value is often not desirable. You might want to set a default value if the key that you are trying to access is sometimes undefined.
This can be tackled using the logical ‘OR’ operator ( || ), like this:
console.log(data.profile.name || ‘John Doe’)
This makes sure that if data.profile.name is undefined then ‘John Doe’ is shown. But this is still not perfect, lets have a look why,
(Code snippet—1.3)
What if the initial value of the key ‘age’ is 0 (which is actually a valid age). In this case, we would get 21 as the output. Which is again not the desired behaviour.
This happens because 0 in javascript is considered a falsy value.
So, until now what we had to do is:
if(data.profile.name == undefined || data.profile.name == null )
{
// keep the value of name as ‘John Doe’
}
else{
//keep the provided value of name
}
This makes your code unnecessarily long, and many inexperienced programmers (including me when I was starting! 🤓 ) introduce bugs unknowingly.
#Tip: Incomplete knowledge is more dangerous than no knowledge.
But now with the introduction of Nullish Coalescing Operator ( ?? ) in ES2020, we can save a lot of time and bugs!
(Code snippet—1.4)
All we have to do is use the ( ?? ) operator in the place of ( || ), as simple as that! And that's all you have to do.
Now this will log 21 only when the value of age is null or undefined. Which is what we expect.
The optional chaining operator ?. permits reading the value of a property located deep within a chain of connected objects without having to validate that each reference in the chain is valid.
let's understand this with the help of an example,
(Code snippet—2.1)
We know from our previous experiences that if we try to access a key that doesn't exist inside an object, we get undefined. ( see Code snippet-2.1)
We are trying to access age (which is not present) from the data object. Hence we get undefined.
(Code snippet—2.2)
Now, what if we try to access a nested key that doesn't exist.
As you can see in the Code snippet — 2.2 that we would get an error.
So if we have two levels of undefined, then we get an error.
This issue can be resolved using the logical ‘AND’ (&&) operator, like this:
console.log(data && data.profile && data.profile.age);
When translated to words it means — if data exists — then extract data.profile — and if data.profile exists — extract data.profile.age
⚠️ Now, this is an okay workaround to solve this issue, but this gets very nasty, very fast. Just imagine if you have a deeply nested object and you want to access a key that is very deep into this object, how many times would you have to use the && operator!
Thus to simplify this we can now use the ES2020 optional chaining operator,
(Code snippet—2.3)
In Code snippet—2.3 you can see how concise and easy to read our code is, which otherwise would have taken several lines.
Another observation to make is that we get the output as undefined. Which is still much better than getting an error and now we can also handle this by merging our learning of Nullish coalescing ( ??) and Optional chaining ( ?. ) operator!
Comment the answer to the problem below! or tweet me🐦 any questions you have!
Previously published at https://dev.to/vikrantbhat/javascript-es2020-nullish-coalescing-and-optional-chaining-explained-3pkg