4 New JavaScript Features To Watch Out for in 2021

Numeric separators, Logical assignment operators, and more

Published on
May 18, 2021

Read time
4 min read

Introduction

Since 2015, JavaScript has enjoyed yearly language updates. 2021 is no different: this year, several new features reached Stage 4 of the TC39 Process and are already available in Node.js and most major modern browsers.

In this article, we’ll look into four of the most important new features. We’ll cover a new string method, a new Promise method, improvements to number readability, and a new shorthand for assignments.

replaceAll()

First, we have a new string prototype method, replaceAll, which replaces every instance of a substring. While we could do this with the existing replace method, we had to turn to regular expressions, such as the following:

"1990-01-01".replace(/-/g, "/");

replaceAll is arguably more readable:

"1990-01-01".replaceAll("-", "/");

With replaceAll, no regex is necessary. It can still be used, though, as long as the g flag is provided.

"1990-01-01".replaceAll(/-/g, "/");

Support:

  • Chrome: 85+
  • Firefox: 77+
  • Safari: 13.1+
  • Node: 15.0.0+

Promise.any

This year has seen further improvements to the handling of asynchronous code with Promise.any, which takes an array of Promises and returns the first one which resolves. If every Promise is rejected, an error is thrown.

Let’s take four Promises and see what happens:

const p1 = new Promise((resolve, reject) => setTimeout(reject, 1000, "p1"));
const p2 = new Promise((resolve, reject) => setTimeout(resolve, 2000, "p2"));
const p3 = new Promise((resolve, reject) => setTimeout(reject, 3000, "p3"));
const p4 = new Promise((resolve, reject) => setTimeout(resolve, 4000, "p4"));

Promise.any will return whichever resolves first. In this case, p2. We can test this using the code below:

async function getFirstResolvedPromise() {
  const result = await Promise.any([p1, p2, p3, p4]);
  console.log(result);
}
getFirstResolvedPromise(); // "p2"

There are now four methods we can use to work with an array of Promises:

  • Promise.all — returns an array of resolved Promises, once all the Promises are resolved
  • Promise.allSettled (new in 2020) — returns an array of Promises, whether they’re resolved or rejected, once all the Promises are resolved or rejected
  • Promise.race — returns the first resolved or rejected Promise
  • Promise.any — returns the first resolved Promise

Support:

  • Chrome: 85+
  • Firefox: 79+
  • Safari: 14+
  • Node: 15.0.0+

Logical Assignment Operators

Since the introduction of the nullish coalescing operator ?? in 2020, we now have three logical operators:

  • && — logical AND
  • ||— logical OR
  • ??— nullish coalescing operator

These shorthands allow us to concisely resolve expressions based on whether a value is truthy or falsy — or, in the case of ??— whether a value is nullish (null or undefined).

Now, we have an even more concise shorthand for assigning values using these operators:

  • &&= — assigns a variable, if the variable is truthy
  • ||= — assigns a variable, if the variable is falsy
  • ??= — assigns a variable, if the variable is nullish

In the code below, each group of three statements are equivalent:

// Logical AND assignment
a &&= b;
a = a && b;
a = a ? b : a;

// Logical OR assignment
a ||= b;
a = a || b;
a = a ? a : b;

// Logical nullish assignment
a ??= b;
a = a ?? b;
a = a === null || a === undefined ? b : a;

In the example below, the variable a will be reassigned a new value when every expression runs. Here’s the code:

let a = true;

const b = false,
  c = null,
  d = 10;

a &&= b;

console.log(a); // falsea ||= c;
console.log(a); // nulla ??= d;
console.log(a); // 10

These new assignment operators join the mathematical assignment operators +=, -=, *=, /=, **= and %=, as well as the bitwise operator assignments.

Support:

  • Chrome: 85+
  • Firefox: 79+
  • Safari: 14+
  • Node: 15.0.0+

Numeric Separators

Finally, this year has seen wide adoption of a feature that brings a significant increase in readability for those working with large numbers or lots of decimal places!

Now, we can use an underscore to separate digits.

const a = 100000000;
const b = 100_000_000;

console.log(a === b); // true

Although a and b are identical, b is much easier to identify as 100 million. In practice, the numeric separator is mainly useful as a thousand separator, though this usage is not enforced. Numeric separators are usable with floats and BigInt values (introduced in 2020). Here’s some code to show how these work:

const float = 3.141_592_653_59;
const bigInt = 9_007_199_254_740_992n;

They’re also supported in hexadecimal, octal and binary numbers, such as hexadecimal 0xFF_FF_FF or 0x_00_00_00.

Note that _ cannot be used at the beginning or end of a number (or after an initial 0). Also, it cannot be adjacent to a decimal point, and multiple underscores cannot be used in a row.

Support:

  • Chrome: 75+
  • Firefox: 70+
  • Safari: 13+
  • Node: 12.5.0+

© 2024 Bret Cameron