Cover image for Nullish Coalescing - Let Falsy Fool You No More

Nullish Coalescing - Let Falsy Fool You No More

laurieontech profile image Laurie Updated on ・3 min read

Languages are constantly changing. And if you've read other posts of mine you know that I love checking in on the latest and greatest in JavaScript.

Just last week TC39 (the committee behind ECMAScript) greenlit a few new awesome features. This week we'll dive into nullish coalescing. Sort of a mouthful of a name, isn't it?

Let's break it down.

Using or to set a default

Often in programming, we can't count on a value existing, and we want to set a default instead. There are a few different ways to do this, but one of the most common is to use or, represented by ||.

let snippet = null

let snippet = snippet || "code snippet"

In this example, snippet is set to null. Since we always want a string, we'll reassign it using the or operator. This expression will keep snippet the same unless snippet is falsy. When it's falsy the expression resolves to "code snippet" instead. That's because falsy values in JavaScript are values that are "considered false when encountered in a Boolean context", like our example above.

Falsy values

The or operator is super helpful! But in JavaScript, falsy values are kind of tricky. They include values like null and undefined, but they also include 0, false, and empty string. Yikes! That means that this expression will evaluate a little differently than we might want it to.

let age = 0

let age = age || 1

In this example, age becomes 1. But 0 is a valid age! We don't want that. We only want to default to 1 if age is not a number.

Note that there is a function isNaN to check this, but we're ignoring that situation for now.

We quickly discover that there are plenty of other situations this causes problems in. My particularly favorite is the empty string case. Oftentimes you don't want a null string variable because it will throw errors when you attempt to manipulate it. But having an empty string is ok.

let message = ""

let message = message || "Welcome to DEV"

However, in JavaScript, empty string is falsy! So message gets set to "Welcome to DEV" even when we don't want it to.

Note that we can check for type of stringValue, but that's annoying.

Along comes nullish coalescing

And that's what this addition is all about. We can replace our || check with the nullish coalescing operator, ??. Using this operator works much the same as ||, with one major exception. If the value on the left-hand side of the operator is null or undefined the default (right-hand side) will be used. Otherwise, the default is ignored.

So let's look at our three examples.

let snippet = null

let snippet = snippet ?? "code snippet"

This will still resolve to "code snippet". snippet is null.

How about in the case of a falsy value like zero?

let age = 0

let age = age ?? 1

age is still 0! 0 is not null or undefined, so the right-hand argument to the operator is ignored.

And finally our empty string example.

let message = ""

let message = message ?? "Welcome to DEV"

message stays an empty string, just like we want.

Well this is awesome

Isn't it?! Falsy values have caused me lots of strife over the years when they caused unintentional side effects, so I'm super psyched for this. Stay tuned for other new features. We'll tackle optional chaining next.


Editor guide
silvestricodes profile image
Jonathan Silvestri

This combined with optional chaining is about to remove 75% of the reason I use lodash and I love it.

lizraeli profile image
Lev Izraelit

Great examples for how valuable the ?? operator is! I think what makes it even better is that we can still use || in the few cases when we want to treat "" and 0 as false. In codebases where this becomes common practice, it will be easy to tell at a glance what values can be expected for the initial variable.

laurieontech profile image
Laurie Author

Absolutely. Addition not replacement is key!

aaron_powell profile image
Aaron Powell

Love this! I transformed our codebase at work with this along with Optional Chaining and it's so much more eloquent.

I also changed array.length > 0 checks for array?.[0] checks when we knew what the array was dealing with.

I do think it's worth mentioning that not all || situations will you want to convert to ?? as there are some very valid scenarios where treating falsy values as false is needed. :)

laurieontech profile image
Laurie Author

Absolutely! And that's definitely something I could have/should have mentioned.

daveskull81 profile image
dAVE Inden

This is rad. Nullish coalescing will be very useful. I’m looking forward to your write up on optional chaining.