JS Tip of the Day: ES2021 Preview

ES2021 Preview
Version: ES2021
Level: Beginner

This series of JavaScript tips started with a couple of new features that were introduced in ES2020. For this tip, the final tip in the series, we will take a look at a few of the features that have been finalized for the next release of the ECMAScript specification, ES2021. These include:

  • Numeric Separators
  • String.prototype.replaceAll()
  • Promise.any()
  • Logical Assignment Operators

Numeric Separators

We’ve already touched upon numeric separators in the Numeric Literal Formats tip. These are underscores that you can add to number literals to make them easier to read. Like comments, when the code is run, they’re ignored, but as a viewer of the source code, they can be useful in showing just how big a number is.

let unknownSize = 1000000000;
let clearlyOneBillion = 1_000_000_000;


Strings are getting a new replace function, replaceAll(). This works much like the existing replace() except that it will inherently replace all instances of a string within another string. With replace(), you could do this, but you’d have to use regular expressions.

let message = "If you have *** dollars, you can get *** bananas.";
console.log(message.replace("***", 3)); // only replaces first
// If you have 3 dollars, you can get *** bananas.

console.log(message.replace(/\*\*\*/g, 3)); // replaces all, but needs regex
// If you have 3 dollars, you can get 3 bananas.

console.log(message.replaceAll("***", 3)); // more easily replaces all
// If you have 3 dollars, you can get 3 bananas.


With Promise.any(), Promise is getting a new static method for resolving a collection of promises in the same vein of Promise.all(), Promise.race(), and the recently added Promise.allSettled(). Promise.any() works by resolving as soon as any promise in the collection is resolved. This is much like Promise.race() except Promise.any() won’t reject unless all of the promises reject. As long as any promise resolves, it will resolve with that value.

let runner1 = Promise.reject('Ouch, I fell!');
let runner2 = Promise.reject('Too tired; going home.');
let turtle = new Promise(resolve => {
    setTimeout(resolve, 3000, 'Slow and steady...');

]).then(motto => {
    console.log(motto, 'Wins!');
/* logs (after 3 seconds):
Slow and steady... Wins!

Logical Assignment Operators

A new set of assignment operators have also been added. These are based on the logical operators OR (||), AND (&&), and nullish coalescing (??). Just like you can have addition assignment with +=, you can also have OR assignment with ||=. These logical assignment operators help reduce repetition of the variable being assigned and prevents the variable from assigning it to itself in cases where it would.

let isTruthy = 'truthy';
isTruthy ||= 'not set'; // much like: isTruthy = isTruthy || 'not set'
console.log(isTruthy); // truthy
isTruthy &&= 'set';
console.log(isTruthy); // set

let isFalsy = 0;
isFalsy &&= 'not set'; // much like: isFalsy = isFalsy && 'not set'
console.log(isFalsy); // 0
isFalsy ||= 'set';
console.log(isFalsy); // set

let nonNullish = 'non-nullish';
nonNullish ??= 'not set'; // much like: nonNullish = nonNullish ?? 'not set'
console.log(nonNullish); // non-nullish

let nullish = null;
nullish ??= 'set';
console.log(nullish); // set

More info:

More tips: JavaScript Tips of the Day

1 Like