JavaScript ES2021- New ES21 features you need to see

Shravani Roy
4 min readApr 20, 2022
Photo by Nick Fewings on Unsplash

The 12th edition of ECMAScript introduces these features:

  • replaceAll
  • Promise.Any
  • AggregateError
  • WeakRef
  • &&=, ||= and ??=
  • Numeric separators

String.prototype.replaceAll

The new replaceAll method for Strings is a nice little addition which replaces all occurrences from a string.

Before replaceAll one would have to use regEx to replace all the character or word occurrences.

// replacing all occurrences of z with a
// jzvzscript becomes javascript
'javascript'.replaceAll('z','a');

Promise.Any and AggregatorError

The new Promise.any function take an iterable of Promises and returns a promise once any one of those Promises get resolved. Juxtaposed with the existing Promise.all which resolved only when all the Promises were resolved, Promise.any is useful when we need only one promise to resolve regardless of what happens to the others. Hence the name -any

const err = new Promise((resolve, reject) => {
reject(new Error('Error'));
});
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('First Promise');
}, 100);
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Second Promise');
}, 200);
});

Prints whichever promise resolves first.

Promise.any([err, p1, p2]).then((res) => {
console.log(res); // Prints "First promise" or "Second Promise"
})

Now, the question arises, what if none of the promises resolve? Well, in that case, the new AggregateError class help us handle the exceptions holding the rejection reasons.

const e1 = new Promise((resolve, reject) => {
reject(new Error('Error 1'));
});
const e2 = new Promise((resolve, reject) => {
reject(new Error('Error 2'));
});
Promise.any([e1, e2])
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
// output: ""AggregateError: No Promise in Promise.any was resolved"

WeakRef

A WeakRef is an object that is used to refer to a target object without preserving it from garbage collection.

As the name suggests, the weakly referenced object will not be kept in memory as long as it is not strongly referenced.

JavaScript uses its garbage collection algorithm to wipe out objects in memory that are no longer referenced by other objects. So, when we create a WeakRef object, it can be garbage collected at any time.

Weak references are useful to implement caches or mappings to large objects. In such scenarios, we do not want to keep a lot of memory for a long time saving this rarely used cache or mappings. We can allow the memory to be garbage collected soon and later if we need it again, we can generate a fresh cache.

const largeObject = new WeakRef({
name: "ECMA2021",
type: "Cache",
implementation: "WeakRef"
});

largeObject.deref();
largeObject.deref().name; //output: "ECMA2021"
largeObject.deref().type; // output: "Cache"
largeObject.deref().implementation; // output: "WeakRef"

Note: Here is a note of caution from TC39 Proprosal while using them!

Logical Assignment Operators

The three new logical assignment operators are:

  • Logical Nullish Assignment (??=)
  • Logical AND Assignment (&&=)
  • Logical OR Assignment (||=)
  1. Logical Nullish Assignment

?? is Nullish Coalescing operator in JavaScript which specifically checks if a value is null or undefined .

var a;
var b = a ?? 12;
console.log(b); //output: 12

Here if a is null or undefined the right hand side of ?? is evaluated ad assigned to b.

Now, let us consider the ?? along with =

const dog = {name: 'Poodle'}
dog.name ??= 'Punch face';
console.log(dog.name) //output: Poodle
dog.colour ??= 'Apricot';
console.log(dog.colour) //output: Apricot

If we were to use older version of ES, the above code would look like this:

const dog = { name: 'Poodle' };
if(dog.name === undefined || dog.name === null) {
dog.name = 'Punch face';
}
console.log(dog.name);
if(dog.colour === undefined || dog.colour === null) {
dog.colour = 'Apricot';
}
console.log(person.colour);

2. Logical AND Assignment (&&=)

var a = 12;
var b = 144;
b &&= a
console.log(b); //output: 12

The logical AND assignment operator &&= will perform the assignment if the left operand is truthy.

To elaborate,

const book = {
stocks: 0,
};
book.stocks &&= 10;
console.log(book.stocks);
// output: 10
book.author &&= 'J.K.Rowling';
console.log(product.author);
// output: undefined

3. Logical OR Assignment (||=)

The logical OR assignment operator (||=) is similar to the nullish assignment, but the left operand should be false for the assignment to occur. A value is considered false if it is null, undefined, false, 0, or Nan.

const book = {
stocks: 0,
};
book.stocks ||= 10;
console.log(book.stocks);
// output: 10
book.author ||= 'J.K.Rowling';
console.log(product.author);
// output: J.K.Rowling

Numeric Separators

Working with large numbers can be confusing. Is 1000000000, one billion? Are you finding difficult to count the number of zeros?

To improve readability ES2021 supports underscores _ which can be placed as numeric separator. When one billion can be written as 1000_000_000 in code, it is way easier to read.

// previous syntax before ES12
const number = 92145723;

// new syntax coming with ES12
const number = 92_145_723;

Wrap Up

ECMAScript keeps evolving with the introduction of cool new features every year. The 12th edition of ES has simplified essential coding functionalities with its enhanced features.

In this article, we explored the top six features of ES12 that you should learn as a JavaScript developer. Hope these features aid your development.

Thank you for reading!

--

--

Shravani Roy

Computer engineering professional. As brave as Internet Explorer. Enjoy traveling and reading my way around the world, always fidgeting, but also practice Zen.