Top 8 Features of ES2021 Every Developer Must Know
Tags: development, javascript, webdev
Published: 2022-08-09 12:41:29

---
title: Top 8 Features of ES2021 Every Developer Must Know
published: true
date: 2022-08-09 11:00:17 UTC
tags: development, javascript, webdev
canonical_url: https://www.syncfusion.com/blogs/post/top-8-features-of-es2021-every-developer-must-know.aspx
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a5bc9mlq0iq6wc168rml.png
---

ES2021 is the 12<sup>th</sup> [ECMAScript](https://en.wikipedia.org/wiki/ECMAScript "Wikipedia page for ECMAScript") version approved by the [TC39 committee](https://tc39.es/ "TC39 committee"). It includes some exciting features every JavaScript developer should know. So, in this article, I will discuss some of the highlights of ES2021 to give you a better understanding.

## Promise.any

The **promise.all()** was introduced with ES2020 to run multiple promises concurrently and act when they were all settled (fulfilled or rejected). With ES2021, **Promise.any()** was introduced, which can handle an array of promises.

The **Promise.any()** method takes a list of promises and returns the value of the first promise that is resolved. In the following example, we pass two promises to the **Promise.any()** method, and it will give an output as soon as the first promise is resolved, since it has the minimum waiting time.

```js
// When all the promises are passed.
const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 10000, "100 second");
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 20000, "200 second");
});

let promises = [promise1, promise2];

Promise.any(promises).then((value) => {
  console.log(value); // outputs “100 second”
})
```

If none of the queued promises resolves, the **Promise.any()** will return a rejected promise returning an **AggregateError** , a collection of all errors found.

```js
// When all the promises are rejected.
const promise1 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, "100 second");
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 2000, "200 second");
});

let promises = [promise1, promise2];

Promise.any(promises).then((value) => {
  console.log(value);
}).catch((err) => { console.log("error: " + err) }) 

// outputs error: AggregateError: All promises were rejected
```

## AggregateError

**AggregateError** is an error subclass that combines multiple errors into a single object.

```js
// Syntax
AggregateError(Array<Error>, “message”);
```

An **AggregateError** is generated if all promises are passed to **promise.any()** fail, following a message describing the error.

```js
// Creating an AggregateError.

try {
  throw new AggregateError(
    [new Error("an error"), new TypeError("Typeof error for some field")], "common error message");
} 
catch (e) {
  console.log(e instanceof AggregateError); // true
  console.log(e.message); // "common erro message" console.log(e.name); //"AggregateError" console.log(e.errors); //[Error: "an error", TypeError: Typeof error for some field]
}
```

As shown, **AggregateError** allows you to retrieve the promise messages that contributed to the error using **AggregateError.errors**.

## WeakRef and Finalizers

WeakRef stands for weak references. Weak references commonly help us to build caches or mappings to larger objects. A WeakRef creates a weak reference to the object passed to it. Since a WeakRef variable is the only reference to an object, the JavaScript engine can safely remove it from memory and free up space when the browser does garbage collection.

Refer to the following code.

```js
//WeakRef variable value can be accessed via the deRef method.
const weakRef = new WeakRef({ 
  age: 13;
});
    
console.log(weakRef.deref().age)
    
// output: 13
```

**Note:**  Please avoid using WeakRef as much as possible since it does not have a guaranteed behavior.

WeakRef and finalizers are two features that go together. The **FinalizationRegistry** method allows you to request a callback after an object has become unreachable (garbage-collected).

First, define a registry with the callback you want to run. Then, call the  **.register**  method on the defined registry with the object you want to observe. It will let you know exactly when the memory of the object is freed by the garbage collector.

Refer to the following code.

```js
const registry = new FinalizationRegistry(value => {
  console.log("Finalizer");
});

registry.register({object: "Do Something"}, "testObject");
```

Here, the object passed to the **register()** method is weakly referenced, so when the value is garbage collected, the second parameter is passed to the finalizer **(testObject)**.

## Numeric separators

This new feature allows you to use underscores as separators for the numeric literals. It increases the readability of the numbers by separating groupings of numbers visually.

Refer to the following example.

```js
// A billion
const amount = 1000000000; // Previous
const amount = 1_000_000_000; // With ES2021

// Hundreds of millions     
const amount = 1475938.38; // Previous
const amount = 1_475_938.38; // With ES2021
```

This is much easier to read now. This does not affect performance or equality. 1000000000 is still equal to 1\_000\_000\_000.

## String.protype.replaceAll

The **replaceAll** method replaces all pattern occurrences with the replacement passed to it. The pattern parameter can be a string or a regex pattern, and the replacement parameter can be either a string or a function.

The **replaceAll** method is an improvement to the **String.replace** method, which can only replace the first occurrence of the pattern.

**Before**

```js
const message = 'hello+good+morning';
const messageWithSpace = message.replace(/\+/g, ' ');

// hello good+morning
```

**After (with method replaceAll)**

```js
const message = 'hello+good+morning';
const messageWithSpace = message.replaceAll('+', ' ')

// hello good morning
```

## Logical Assignment Operators

Three new logical assignment operators were introduced in the **ECMAScript 2021** update. These operators are pretty similar to the existing logical operators, and they help assign values to variables in a single line.

1. Logical OR assignment operator ||=
2. Logical AND assignment operator &&=
3. Logical nullish assignment operator (??=)

**Logical OR assignment operator (||=)**

```js
p ||= q

// This is exactly identical to the below expression.
if (!p) {
  p = q
} 

// If p is false, q will be assigned to it. Otherwise, p is left at its original value.
```

**Logical AND assignment operator (&&=)**

```js
p &&= q

// This is exactly identical to the below expression.
if (p) {
  p = q
} 

// If p is true, q will be assigned to it. Otherwise, p is left at its original value.
```

**Logical nullish assignment operator (??=)**

```js
x ??= y
```

This only assigns y to x if x is either null or undefined.

## Private Accessors

Private accessors work very similarly to private methods. So, let’s create a simple class with a private method to understand the difference.

**Previous versions**

```js
class ExampleClass {
  MyMethod1() {
    console.log("Public method")
  }
  #MyMethod2() {
    console.log("Hidden method")
  }
}

const exampleClass= new ExampleClass ()

exampleClass.MyMethod1()
exampleClass.MyMethod2()

// output
// Public method
// exampleClass.MyMethod2 is not a function.
```

In the previous ECMAScript versions, we can’t call **MyMethod2()**, since it is a private method. If you run the previous code, it will give an error saying that the **exampleClass.MyMethod2** is not a function.

**With ES2021**

With the ES2021 updates, we can create a new public method called inside the class **(callAll() )**, and access the private method.

```js
class ExampleClass {
  MyMethod1() {
    console.log("Public method")
  }
  #MyMethod2() {
    console.log("Hidden method")
  }
  callAll() {
    this.MyMethod1()
    this.#MyMethod2();
  }
}

const exampleClass = new ExampleClass()
exampleClass.callAll(); 

// output
// Public method
// Hidden method
```

Like private methods, we can now define getters and setters in JavaScript, making them only accessible inside a class or by an instance created.

```js
class ExampleClass {
  get #Greeting() {return "Hello Good Morning !" 
  }
  
  get viewGreetingMsg() {
    return this.#Greeting
  }
}

let exampleClass = new ExampleClass();
console.log(exampleClass.viewGreetingMsg);

// Hello Good Morning !
```

## dateStyle and timeStyle options for Intl.DateTimeFormat

The **Intl.DateTimeFormat** can enable language-sensitive date and time formatting. The proposed **dateStyle** and ** timeStyle** options allow us to request a locale-specific date and time of a given length.

```js
// Time with short format let. 
let time = new Intl.DateTimeFormat('en' , { timeStyle: 'short' });
console.log(time .format(Date.now())); // 09:27 PM 

// Time with medium format.
let time = new Intl.DateTimeFormat('en' , { timeStyle: 'medium'});
console.log(time .format(Date.now())); //09:27:50 PM 

// Time with long format. 
let time = new Intl.DateTimeFormat('en' , { timeStyle: 'long' }) ;
console.log(time .format(Date.now())); // 11:27:50 PM GMT+11
```

## Conclusion

In this article, I discussed the top eight highlights of the ES2021 update. I hope this article helped you to improve your JavaScript knowledge. Thank you for reading.

Syncfusion [Essential JS 2](https://www.syncfusion.com/javascript-ui-controls "Essential JS 2 UI Controls") is the only suite you will ever need to build an app. It contains over 65 high-performance, lightweight, modular, and responsive UI components in a single package. Download a [free trial](https://www.syncfusion.com/downloads/essential-js2 "Free evaluation of the Syncfusion Essential Studio") to evaluate the controls today.

If you have any questions or comments, you can also contact us through our [support forums](https://www.syncfusion.com/forums "Syncfusion support forums"), [support portal](https://support.syncfusion.com/ "Syncfusion support portal"), or [feedback portal](https://www.syncfusion.com/feedback/ "Syncfusion feedback portal"). We are always happy to assist you!

## Related blogs

- [5 Different Ways to Deep Compare JavaScript Objects](https://www.syncfusion.com/blogs/post/5-different-ways-to-deep-compare-javascript-objects.aspx "Blog: 5 Different Ways to Deep Compare JavaScript Objects")
- [JavaScript Higher-Order Functions: A Complete Guide](https://www.syncfusion.com/blogs/post/javascript-higher-order-functions-a-complete-guide.aspx "Blog: JavaScript Higher-Order Functions")
- [Improve the Usability of JavaScript Web Applications with Web Vitals](https://www.syncfusion.com/blogs/post/how-to-improve-the-usability-of-javascript-web-applications-with-web-vitals.aspx "Blog: Improve the Usability of JavaScript Web Applications with Web Vitals")
- [What’s New in 2022 Volume 2: Essential JS 2](https://www.syncfusion.com/blogs/post/whats-new-in-2022-volume-2-essential-js-2.aspx "Blog: What’s New in 2022 Volume 2: Essential JS 2")