Logo of The Bit Bang Theory blog

ECMAScript 2021: The New Features

  ·  10 minutes read


ES2021 (or ES12) is the ECMAScript version corresponding to the year 2021. This version doesn’t introduce as many new features as those that appeared in ES6, back in 2015. Nonetheless, some valuable features have been included.

Before moving on, let me clarify something. This article was written on February 12, 2021, based on the ES2021 Release Candidate. The features listed in that release require approval from the ECMA General Assembly and such approval is expected to be granted by June 2021. From that moment, these features will be—officially—part of the standard per se.

It's worth mentioning that—at the time of writing—all of the features enumerated here are supported by the Google Chrome Canary build. You're free to try them all there.

Without further ado, let's review the most interesting features that the new version of the specification makes available to us.

1. Logical Assignment Operators

The new logical assignment operators&&=, ||= or ??= combine the logical operations with the assignment operation. They are positively similar to the current logical operators and are very helpful for assigning default values to variables.

Logical AND Assignment Operator (&&=)

The logical AND assignment operator is the antithesis of the logical OR assignment operator. In the expression x &&= y, y is assigned to x, if and only if x is a truthy value. Otherwise, it preserves its initial value.

Snippet of code showing the functionality of the logical and assignment operator

Logical OR Assignment Operator (||=)

The logical OR assignment operator is, in turn, the antithesis of the logical AND assignment operator. It is s a short-circuit operation just like the logical OR operator (||).

The expression x ||= y is identical to the expression x || (x = y). This means that y will be assigned to x, if and only if x represents a falsy value. Otherwise, it preserves its initial value.

Snippet of code showing the functionality of the logical or assignment operator

Logical nullish Assignment Operator (??=)

The logical nullish assignment operator only assigns y to x, if x is nullish (i.e., if x is either null or undefined).

Snippet of code showing the functionality of the logical nullish assignment operator

In this example, the output is "theKey" because userDetails.key does not exist in the response object (i.e., it is undefined).

2. String.replaceAll()

This is a suitable method that addresses a particular shortage in String.replace(): the inability to replace all the occurrences of a pattern with a new string (in that case, one had to make use of regular expressions to achieve such a task).

Now, with the introduction of String.replaceAll() to the language, we can easily replace all occurrences of a given string.

Snippet of code showing the syntax of the Spring.prototype.replaceAll method

Syntax of the String.replaceAll() method.

The String.replaceAll() method returns a new string in which all occurrences of a pattern are replaced by a replacement passed to it. The pattern parameter can either be a string or a regex pattern, and the replacement parameter can either be a string or a function that creates a new string to replace the pattern. This method operates without altering the old string.

Snippet of code showing the functionality of the Spring.prototype.replaceAll method

At the time of writing, this method lacks support on Node.js, but most browsers already implemented it.

3. Promise.any() and AggregateError

Snippet of code showing the definition of the Promise.any method

Syntax of the Promise.any() method.

Promise.any() takes an iterable of Promise objects and, as soon as one of the promises in the iterable fulfills, it returns a single promise that resolves with the value from that fulfilled promise. If no promises in the iterable fulfill (i.e., if all of the given promises are rejected), then the returned promise is rejected with an AggregateError, a new subclass of Error that groups together individual errors. In essence, the Promise.any() method is the opposite of Promise.all().

Snippet of code showing the functionality of the Promise.any method

Now, back to the scenario in which none of the promises passed to Promise.any() fulfills (which also takes into account the case where the iterator passed is empty), we need to catch the exception and handle it.

Snippet of code showing the functionality of the Promise.any method

For demo purposes, we passed one to-be-rejected promise to Promise.any(). As a result, the above code logs the following error in the console.

Snippet of code showing the AggregateError logged on the Chrome's console

Promise.any() has a decent support on web browsers yet no implementation has been done on Node.js at the time of writing.

4. Numeric separator

ES2021 introduced the numeric separator to improve the readability of large numbers. As a result, we will be allowed to use the underscore (_) character to separate number groups, just like we use commas to separate numbers in writing.

Take a look at the number 1197982359, which is the approximate number of live websites in 2020. At first, it's not particularly easy to spot that is a number of the billion order.

Snippet of code showing the functionality of the numeric separator syntactic sugar in JavaScript

We can see that with cosmetic addition, the number can be read more easily.

Please note that this has no performance benefits at all. 1197982359 will still be exactly equal to 1_197_982_359.

As for support, this feature is already implemented in most browsers and on Node.js since version 12.5.0.

5. Intl.ListFormat

Before exploring how this new constructor works, let's recall what the Intl object is: a namespace for the ECMAScript Internationalization API, which supplies a collection of helper methods to support internalization efforts, like language-sensitive string comparison, number formatting as well as date and time formatting.

Consequently, the Intl.ListFormat object enables language-sensitive list formatting. Its constructor—ListFormat—creates and returns a formatter object that (depending on the configuration passed upon creation) will join lists of strings using the best localized conventions.

Let's take a look at an example to better illustrate this.

Snippet of code showing the functionality of the Intl.ListFormat constructor method

The first (optional) argument for the ListFormat constructor is the language to be used—'en' for English in the example above. You can also pass an array of these BCP 47 Language Tags.

The second (also optional) parameter is an object with three (also optional) fields:

  • "localeMatcher" — sets the locale matching algorithm to be used; it can be either "lookup" or "best fit" (which is the default one).
  • "style" — which affects the separators used to join the input strings, and can be either "long", "short", or "narrow".
  • "type" — regulates the format of the output message; it can be either "conjunction", "disjunction", or "unit".

6. New options for Intl.DateTimeFormat: dateStyle and timeStyle

Intl.DateTimeFormat is a constructor for a language-sensitive date and time formatter, long-supported in the JavaScript ecosystem.

These new options allow us to control the length of the local-specific formatting of date and time strings.

Let's see some examples on how to use it when working with times...

Snippet of code showing the functionality of the Intl.DateFormat method with the timeStyle option

... and with dates

Snippet of code showing the functionality of the Intl.DateFormat method with the dateStyle option

We can also combine the two options to get a date-time string:

Snippet of code showing the functionality of the Intl.DateFormat method with both the timeStyle and dateStyle options


JavaScript is a constantly evolving language, and that’s something very healthy for web development. Since the advent of ES6 in 2015, we’re experiencing an active evolution of the language. In this article, we’ve examined the most interesting features introduced by ES2021.

Although many of these features may not be significant for your development workflow, they address situations that could only be achieved before with tricks or great verbosity.

Back to Home