Nullish Coalescing Operator (??)

Nullish Coalescing Operator (??)

ยท

6 min read

Hey folks, I am pretty sure you guys would have read a lot of blogs on nullish operator most of you would have understood it well in the first go, while most of you will be still struggling. Well for me it seemed pretty easy to understand nullish operator (??) until one day I encountered one bug in one of the functionalities I was implementing.

So before we start let's understand the flow of all things we will cover in this blog. We will go through the history of why the nullish coalescing operator was introduced, what problem it solved, and lastly some of the rules about the nullish operator.

So let's first start with the OR operator.

OR (||) Operator

So let's try to understand how we used OR short-circuiting operator earlier to assign values to variables. What OR operator does is return the first truthy value in an expression. It evaluates an expression from left to right. So if the left-hand side value is a falsy value then the right-hand side value is evaluated.

Let's take an example:

let score = 23

let result = score || 10
console.log(result)
// prints 23

In the above example, you can see that score is the variable we have defined. We check whether the score is truthy value or not. If it's a truthy value it will return the value but if it's a falsy value it will return the next value which is 10 in our case.

But the is one problem here we are trying to check whether there is a value for the score variable or not and based on that value we will assign the second value. Now consider this below code.

let score = 0

let result = score || 10
console.log(result)
// prints 10

Here we have defined our score as 0, but when we check for score it is using OR operator we get our score as 10. We wanted to have our score as 0 but as OR evaluates the score as a falsy value we get result as 10. Falsy values in javascript are ""(empty string), 0, NaN, undefined, null and false.

So to solve this issue nullish coalescing operator (??) was introduced.

Nullish Coalescing Operator

Nullish coalescing operator is represented using double question mark "??". The way the nullish operator solves this issue is it checks for null and undefined values. So now if we tried this same operation as above using "??" we can assign zero as well. Let's see how.

let score = 0
let count;

let result = score ?? 10
console.log(result)
// prints 0

let totalCount = count ?? 1;
console.log(totalCount);
// prints 1

In the above code snippet, you can see that the nullish operator checks for null and undefined values only. For the first expression, we get the value in the result variable as 0. In the second expression, the value of the totalCount is evaluated as 1 because count has undefined as a value.

So now the drawbacks of the OR operator can be avoided using the nullish operator.

43sh23_z0rtki.jpg

Well, the nullish coalescing operator is not something new. It's a kind of betterment for the OR operator to get the first defined value rather than a falsy value.

We can write the same logic differently as well. Check this below example:


let score = 0
let count;

let result = (score !== null && score !== undefined) ? x : 10
console.log(result)
// prints 0

The above code achieves the same result as that of nullish coalescing. Still, we prefer the nullish operator because it makes our expression smaller. It avoids the efforts of writing extra code and also makes it look cleaner and readable.

Logical Nullish Assignment(??=)

A logical nullish operator is used to check whether a variable is null or not and assigns a value to that variable.


let count;
count ??= 21;

In the above code, you can see that the count variable is assigned the value of 21. Let's check the equivalent expression to this logical nullish assignment:


// Equivalent expression 
count ?? (count = 21)

// Wrong assumption - This not how nullish assignment works
count = count ?? 21

From the above code example, you may think what's the difference between the two. In the second expression, we are assigning the value irrespective of whether the variable was null or not. While in the first one the assignment part is happening only if the variable is null.

Chaining with AND(&&) and OR(||)

Javascript doesn't allow us to chain ?? with AND (&&) and OR (||) operator. Such expressions will give a use syntax error.


"hello" || null ?? 34;
undefined ?? 23 && "welcome" 

// Both the expressions above will give a syntax error

But there is a way to use such chaining by using round parenthesis. Round parenthesis explicitly indicates the precedence of the operator and the expression works correctly.


("hello" || null) ?? 34;
undefined ?? (23 && "welcome")

Bonus Section

Well almost forget you to tell about the bug that I encountered while working with a nullish operator. Check this below code:


const charCount = {}
const string = "check character count in this string"

for(let ch of string){
  charCount[ch] = charCount[ch] ?? 0 + 1;
}

console.log(charCount)

Here I was trying to count the characters in a string and store it in an object, but the above code won't work. What I was trying to do here in this code was check if the property of the current character was present in an object. If the property is present it will consider the value or it will consider 0 and add it to 1. Over the next iteration if the same character is encountered it will consider the value of charCount[ch] and add 1 to it.

Well if you can guess where it went wrong. Kudos to you. But if you didn't no issue took me 4 hours straight to figure out what went wrong ๐Ÿ˜…. Let's make a simple change to the same code and now it will work perfectly fine


const charCount = {}
const string = "check character count in this string"

for(let ch of string){
  charCount[ch] = (charCount[ch] ?? 0) + 1;
}

console.log(charCount)

Yup, parenthesis it is.

040-what-about-parenthesis(2).png

Earlier the code was calculating addition first i.e., it used to add 0 to 1 first and the nullish operator is evaluated this would give 1 every single time. These arithmetic operators have higher precedence than null operator. So the learning here was to check precedence as well while working with a nullish operator. If this last bonus section confused you no issues you can feel free to skip it.

Thank you ๐Ÿ˜Š for sticking it to the very end. I hope you would have got some extra insights for the nullish operator and would probably start using it in your code. If you have any queries feel free to comment below with your questions.

ย