A Practical Example of Nullish Coalescing

Jun 03, 2020 | Mark Brouch

A Practical Example of Nullish Coalescing

Note: This article originally appeared on Medium and has been reposted on the Doximity Technology Blog with the author’s permission.

Nullish coalescing is a brand new logical operator (??) for the JavaScript programming language. It was released along with a whole slew of other new features on April 2nd this year as part of ECMAScript version 2020 (or ES2020).

This new operator is very similar to the logical OR (||) operator, with the exception that it only returns the right-hand side operand when the left-hand side operand evaluates to being nullish. This means that nullish coalescing returns the right-hand side operand when the left-hand side evaluates to undefined or null, but not false, 0, or "" as it will with the logical OR operator.

// These will return the left-hand side operand
// with nullish coalescing, but not OR

false || true // returns true
false ?? true // returns false

0 || true // returns true
0 ?? true // returns 0

"" || true // returns true
"" ?? true // returns ""

// These will return the right-hand side operand
// with nullish coalescing, same as OR

undefined || true // returns true
undefined ?? true // returns true

null || true // returns true
null ?? true // returns true


Drake explains nullish coalescing. ES2020 Bling?

This is pretty cool, but how can it improve the way we write code? Today I came across the perfect use of nullish coalescing. Of course there are plenty more great uses for this new operator, but I thought I’d share how it worked for me.

I was working on a modal component with the typical functionality you might find in any modal. What I was tasked with changing on this particular modal was to create a beforeClose() hook that would be provided by the application and executed by the modal prior to closing. Additionally, I needed to make it so that if the beforeClose() hook returned false, closing the modal should be prevented, that way the application can control whether the modal can close when a close event is initiated, such as by clicking the “close” button.

The modal logic therefore resembles the following:

class Modal {
  constructor(options = {}) {
    this.beforeClose = options.beforeClose || () => {}
  }

  handleClose() {
    beforeClose()
    this.close()
  }

  close() {
    // close the modal
  }
}

Here, when a new Modal is created, it can be provided with a beforeClose option that is a function which will be executed before the modal closes. The handleClose() method is called any time an action occurs that should cause the modal to close, and it calls the provided beforeClose hook before calling the modal’s close() method. However, we still need to implement logic that will prevent the modal from closing if the beforeClose() hook returns false. Prior to ES2020’s nullish coalescing operator, you might attempt to handle this with a simple logical AND statement:

handleClose() {
  beforeClose() && this.close()
}

This will ensure the modal only closes if beforeClose() returns a truthy value. However, this is problematic because what if the beforeClose() hook doesn’t return at all? It would be unreasonable when designing this modal component to assume all implementations explicitly return a truthy value, and furthermore the default beforeClose() hook’s value is a no-op function that returns undefined! To handle this, we’d need to be more explicit in our evaluation of our left-hand side operand:

handleClose() {
  beforeClose() !== false && this.close()
}

This solution is both less elegant, and still does not handle other falsey values like 0 or "" (think Bash’s exit 0 script style). To do that, we’d have to really disfigure our elegant one-liner, and that makes me sad:

handleClose() {
  const shouldClose = beforeClose()
  if (shouldClose !== false &&
  shouldClose !== 0 &&
  shouldClose !== "") {
    this.close()
  }
}

(We could alternatively check for null or undefined, but that’s only slightly better.)

ES2020 has entered the chat

This is where ES2020 comes to the rescue with nullish coalescing:

handleClose() {
  beforeClose() ?? this.close()
}

Ahhh, much better! We’re back to an elegant one-liner logical operator that clearly shows that if beforeClose() returns false we should not close the modal. Returning null or undefined (such as in the case of a function with no return statement) will still allow the modal to close.

As you can see, this new operator enables us to write more succinct, elegant, and understandable code, which is always important because code is meant to be read by humans after all.

Nullish coalescing already has wide browser support among current versions, and is easily back-ported along with the rest of ES2020 new features via a transpiler like Babel. You can read more about this new operator on MDN and the tc39 proposal.


Photo credits: Mark Brouch
Cover image: Dyes made from natural materials coalesce to form the pigments used to color wool in Oaxaca, Mexico.


Be sure to follow @doximity_tech if you'd like to be notified about new blog posts.