ES2021 Features with simple examples
Tags: javascript, webdev, node, es2020
Published: 2021-01-02 11:09:20

---
title: ES2021 Features with simple examples
published: true
description: ES2021 aka ES12 is the version of ECMAScript corresponding to the year 2021. This version does not include as many new features as those that appeared in ES6 (2015). However, some useful features have been incorporated.
tags: javascript, webdev, node, ES2020
series: understanding-javascript
cover_image: https://cdn-images-1.medium.com/max/1200/1*_WJbyOV8GaHKulGO2v4eew.jpeg
canonical_url: https://www.carloscaballero.io/es2021-features-in-simple-examples
---

# Introduction

ES2021 is the version of ECMAScript corresponding to the year 2021. This version doesn’t include as many new features as those that appeared in ES6 (2015). However, some useful features have been incorporated.

This article introduces the features provided by ES2021 in easy code examples. In this way, you can quickly understand the new features without the need for a complex explanation.

Of course, it’s necessary to have a basic knowledge of JavaScript to fully understand the best ones introduced.

The new JavaScript **features in ES2021** are:

➡️ String.prototype.replaceAll
➡️ Promise.any
➡️ WeakRef
➡️ Logical Assignment Operators
➡️ Numeric separators

---

## String.protype.replaceAll

Currently there is no way to replace all instances of a substring in a string without use of a global regexp (/regexp/g). 

```javascript
const fruits = '🍎+🍐+🍓+';
const fruitsWithBanana = fruits.replace(/\+/g, '🍌');
console.log(fruitsWithBanana); //🍎🍌🍐🍌🍓🍌
```

A new replaceAll method has been added to the String prototype.

```javascript
const fruits = '🍎+🍐+🍓+';
const fruitsWithBanana = fruits.replaceAll('+', '🍌');
console.log(fruitsWithBanana); //🍎🍌🍐🍌🍓🍌
```

---

# Promise.any

Promise.any gives you a signal as soon as one of the promises fulfills. This is similar to Pormise.race , except any doesn’t reject early when one of the promises rejects.

```javascript
const myFetch = url => setTimeout(() => fetch(url), Math.floor(Math.random() * 3000));

const promises = [
   myFetch('/endpoint-1'),
   myFetch('/endpoint-2'),
   myFetch('/endpoint-3'),
];

// Using .then .catch
Promise.any(promises) // Any of the promises was fulfilled.
       .then(console.log) // e.g. '3'
       .catch(console.error); //All of the promises were rejected.

// Using async-await
try {
   const first = await Promise.any(promises); // Any of the promises was fulfilled.
   console.log(first);
}catch (error) { // All of the promises were rejected
   console.log(error);
}
```

---

## WeakRef

The WeakRef proposal encompasses two major new pieces of functionality:

 1. creating *weak references* to objects with the WeakRef class.

 2. running user-defined *finalizers* after objects are garbage-collected, with the FinalizationRegistry class.

These interfaces can be used independently or together, depending on the use case

A WeakRef object contains a weak reference to an object, which is called its *target* or *referent*. **A *weak reference *to an object is a reference that does not prevent the object from being reclaimed by the garbage collector.**

A primary **use for weak references is to implement caches or mappings holding large objects**, where it’s desired that a large object is not kept alive solely because it appears in a cache or mapping.


```javascript
function toogle(element) {
   **const weakElement = new WeakRef(element);** 
   let intervalId = null;
     
   function toggle() { 
     **const el = weakElement.deref();**
     if (!el) {
        return clearInterval(intervalId);
    }
    const decoration = weakElement.style.textDecoration;
    const style= decoration === 'none' ? 'underline' : 'none';
    decoration = style;
   }
   intervalId = setInterval(toggle, 1000);
 }

 const element = document.getElementById("link");

 toogle(element);
 setTimeout(() => element.remove(), 10000);
```

`FinalizationRegistry` provides a way to request that a *cleanup callback* (*finalizers*) get called at some point when an object registered with the registry has been *reclaimed* (`garbage-collected`). 

You create the `registry` passing in the callback:

```javascript
const registry = new FinalizationRegistry(heldValue => {
  // ....
});
```

Then you `register` any objects you want a cleanup callback for by calling the register method, passing in the object and a **held value** for it:

```javascript
registry.register(theObject, "some value");
```

---

# Logical Assignment Operators

Logical assignment operators combine logical operators and assignment expressions. There are two new operators:

 1. **Or Or Equals.**
 2. **And And Equals.**

```javascript
// Or Or Equals
|   a   |   b   | a ||= b | a (after operation) |
| true  | true  |   true  |        true         |
| true  | false |   true  |        true         |
| false | true  |   true  |        true         |
| false | false |   false |        false        |

a ||= b
// Equivalent to:
a || (a = b);

// And And Equals
|   a   |   b   | a ||= b | a (after operation) |
| true  | true  |   true  |        true         |
| true  | false |   false |        false        |
| false | true  |   false |        false        |
| false | false |   false |        false        |

a &&= b
// Equivalent to:
a && (a = b);
```

---

# Numeric separators

This feature allows that numeric literals will be more readable using a visual separation between groups of digits.

Using underscores (_, U+005F) as separators helps improve readability for numeric literals:

```javascript
1_000_000_000           // A billion
101_475_938.38          // Hundreds of millions

const amount = 12345_00;  // 12,345 (1234500 cents, apparently)
const amount = 123_4500;  // 123.45 (4-fixed financial)
const amount = 1_234_500; // 1,234,500

0.000_001 // 1 millionth
1e10_000  // 10^10000 -- granted, far less useful / in-range...
    
const binary_literals = 0b1010_0001_1000_0101;
const hex_literals = 0xA0_B0_C0;
const bigInt_literals = 1_000_000_000_000n;
const octal_literal = 0o1234_5670;
```

---

# Conclusion

JavaScript is a live language, and that’s something very healthy for web development. Since the appearance of ES6 in 2015, we’re living a vibrant evolution in the language. In this post, we’ve reviewed the features that arise in ES2021.

Although many of these features may not be essential for the development of your web application, they’re giving possibilities that could be achieved before with tricks or a lot of verbosity.