allBlogsList

Optional Chaining and Nullish Coalescing in JavaScript

> Two new operators have arrived in JavaScript - optional chaining and nullish coalescing. They may sound intimidating but they are actually quite simple, and also quite useful - enabling us to write cleaner, more succinct, human-readable code. Additionally, they also compliment each other nicely. In this post I'll quickly explain what they are and how they work, so you can bolster your JavaScript toolset with these two additional tools.


Optional Chaining

At some point or another, most of us have had to write something close to the following:

    let someVal;

    if (foo && foo.bar && foo.bar.baz) {
        someVal = foo.bar.baz.qux;
    }

In case you have not seen this - it is done because we can't guarantee that foo, bar, and baz all exist. If we simply tried to use someVal = foo.bar.baz.qux - then we'd get an Uncaught TypeError error if one of those properties were nonexistent. This is where the optional chaining operator comes in handy.

The optional chaining operator is represented by a question mark proceeded by a dot - ?.. Here's how we use it to rewrite the example above:

    const someVal = foo?.bar?.baz?.qux;

As you can see this is much, much more succint. The way this works is if any of those properties do not exist - let's say foo is missing - then the operator will short-circuit and return undefined.

Note that optional chaining can be used with expressions and function invocations as well:

    const someProp = 'bar';

    foo?.[someProp];

    const foo = {
        bar: () => console.log('hello world'),
    };

    foo?.bar();

Nullish Coalescing

Imagine you wanted to set a default value for a configuration option, such as a timeout:

    function doSomething(config) {
        const timeout = config.timeout || 2000;

        window.setTimeout(doSomethingElse, timeout);
    }

... This works well for most cases, but what if the passed in configuration value was 0? The OR (||) operator will return 2000 because 0 is a "falsy" value. Now you have a bug in your code. Consumers of doSomething() would get a 2 second timeout when they expected a 0 second timeout.

This is the scenario where the nullish coalescing operator comes in handy. It is represented by two question marks - ??, and can be used like so:

    function doSomething(config) {
        const timeout = config.timeout ?? 2000;

        window.setTimeout(doSomethingElse, timeout);
    }

The nullish coalescing operator works by only checking for null and undefined values. This solves our problem. Even if config.timeout is set to 0 - we still get the expected behavior.

Note that you cannot chain the nullish coalescing operator directly with the AND or OR operators:

    foo || bar ?? 'fallback value'; // does not work
    (foo || bar) ?? 'fallback value'; // works!

Wrapping it up

In the introduction I stated that these two operators work well together. Here's how we could combine both of them, reusing our first example except this time providing a fallback value:

    const someVal = foo?.bar?.baz?.qux ?? 'fallback value';

And to fully appreciate this simplicity, here is how we would (previously) have to write that same code:

    let someVal;

    if (foo && foo.bar && foo.bar.baz) {
        if (typeof foo.bar.baz.qux !== 'undefined' && foo.bar.baz.qux !== null) {
            someVal = foo.bar.baz.qux;
        } else {
            someVal = 'fallback value';
        }
    }

I hope you found this post helpful, and I highly encourage you to start using these operators in your code today!