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 resolvedPromise.allSettled
(new in 2020) — returns an array of Promises, whether they’re resolved or rejected, once all the Promises are resolved or rejectedPromise.race
— returns the first resolved or rejected PromisePromise.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+
Related articles
You might also enjoy...
I Fixed Error Handling in JavaScript
How to steal better strategies from Rust and Go—and enforce them with ESLint
14 min read
How to Easily Support ESM and CJS in Your TypeScript Library
A simple example that works for standalone npm libraries and monorepos
5 min read
Bad Abstractions Could Be Ruining Your Code
Why the ‘Don’t Repeat Yourself’ principle might be doing more harm than good
6 min read