New JavaScript Features ECMAScript 2021 (with examples)
Tags: javascript, ecmascript, 2021, programming
Published: 2021-04-27 20:10:39

**ECMAScript 2021** is the version of ECMAScript corresponding to this year. There are some useful and awesome features that have been incorporated and could be used in our javascript projects

The new JavaScript features in **ECMAScript 2021** are:

- Numeric separators
- String replaceAll
- Logical assignment operator
  - And & Equals (&&=)
  - OR & Equals (||=)
  - Nullish Coalescing & Equals (??=)
- Promise.any
- WeakRef 
- Finalizers

## Numberic separators
This new feature allows numeric literals use underscores as separators to help to improve readability using a visual separation between groups of digits. 

### Example
```javascript
// A billion
const amount = 1_000_000_000;

// Hundreds of millions     
const amount = 1_475_938.38;

// 6234500 cents (62345 dollars)
const amount = 62345_00;

// 1,734,500
const amount = 1_734_500; 

// 20^30000
const amount = 2e30_000;

// Also can be used for Binary, Hex, Octal bases
```

## String.protype.replaceAll
Currently, there is no way to replace all instances of a substring without the use of global regexp `(/regex/g)`. With the new method replaceAll that change that.

### Example
#### Before (with regex)
```javascript
const message = 'hello+this+is+a+message';
const messageWithSpace = message.replace(/\+/g, ' ');

// hello this is a message
```

#### After (with new method replaceAll)
```javascript
const message = 'hello+this+is+a+message';
const messageWithSpace = message.replaceAll('+', ' ')

// hello this is a message
```

## Logical assignment operator
Logical assignment operators combine logical operators and assignment expressions. 

There are some new operators:
- And & Equals (&&=)
- OR & Equals (||=)
- Nullish Coalescing & Equals (??=)

### And & Equals (&&=)
Assign when the value is truthy. Also in the next table is explained. 

With constants, x and y with a value of **true** when the constant has a value assigned and **false** in the opposite case.


|x | y | x And & Equals y | x after assign |
| -- | -- | -- | -- |
|true |true |true |true |
|true |false|false|false|
|false|true |false|false|
|false|false|false|false|

#### Before
```javascript
let a = 1;
if(a){
  a = 8;
}

// Output: a = 8
```
#### After
```javascript
let a = 1;
a &&= 3

// Output: a = 3
```

### OR & Equals (||=)
Assign when the value is falsy. Also in the next table is explained.

With constants, x and y with a value of **true** when the constant has a value assigned and **false** in the opposite case

| x | y | x OR & Equals y  | x after assign |
| -- | -- | -- | -- |
|true |true |true |true |
|true |false|true |true |
|false|true |true |true |
|false|false|false|false|

#### Before
```javascript
// If conditional
let a = undefined;
if(!a){
  a = 5;
}

// Output: a = 5

// OR
a = a || 3;

// Output: a = 3
```
#### After
```javascript
let a = 0;
a ||= 3

// Output: a = 3
```

### Nullish Coalescing & Equals (??=)
Assign when the value is null or undefined. 
```javascript

let a = undefined; 
a ??= 7

// Output: a = 7
```

## Promise.any method
The Promise.any() method returns a promise that will resolve as soon as one of the promises is resolved. If all of the promises are rejected, the method will throw an AggregateError exception holding the rejection reason

### Example
```javascript
const firstPromise = new Promise((resolve, reject) => {
  setTimeout(() => reject(), 1000);
});

const secondPromise = new Promise((resolve, reject) => {
  setTimeout(() => reject(), 2000);
});

const thirdPromise = new Promise((resolve, reject) => {
  setTimeout(() => reject(), 3000);
});

try {
  const first = await Promise.any([
    firstPromise, secondPromise, thirdPromise
  ]);
  // Any of the promises was fulfilled.
} catch (error) {
  console.log(error);
  // AggregateError: All promises were rejected
}
```

## WeakRef
The WeakRef, which stands for Weak References, allows you to create a weak reference to an object. A weak reference to an object is a reference that does not prevent the object from being reclaimed by the garbage collector.

The primary use of Weak Reference is to implement caches or mappings of large objects. Where it’s desired that a large object is not kept alive solely because it appears in a cache or mapping.

### Example
```javascript
const objectExample = {name: "Juanito", lastname: "Jordan"};
const refObj = new WeakRef(objectExample);
```

When you need to read the value of WeakRefs, need to use the deref() method to return the instance.

```javascript
const objectExample = {name: "Juanito", lastname: "Jordan"};
const refObj = new WeakRef(objectExample);
const obj = refObj.deref();
obj.name

// Output: 'Juanito'
```

### Warnings
The detail with the WeakRef feature is that the implementation detail of when, how, and whether JavaScript garbage collector occurs or not, you may observe different behavior between environments. Also, the complexity of the Javascript garbage collector is very high.

For that reason, use WeakRef is not recommended and it’s best to avoid implementing one if possible. Unless you’re a JavaScript library maintainer, you will most likely never need to use it. More information [WeakRefs TC39 proposal](https://github.com/tc39/proposal-weakrefs)

## Finalizers
The Finalizer is a companion feature of WeakRef that allows you to execute some specific code after an object has become unreachable to the program.

In short, you can register a callback function that gets triggered after the garbage collection occurs. You can create a registry bypassing the callback to the FinalizationRegistry.

### Example
```javascript
const registry = new FinalizationRegistry(value => {
  // Do some stuff
});
```

Then, you can register any object you want to clean up for by calling the register() method, passing both the object and the value you want to pass to the callback function.

```javascript
registry.register({greeting: "Hello World"}, "greetingObject");
```

The object passed into the register() method will be weak referenced so when the value will be garbage collected the second param will be passed to the finalizer ("greetingObject" param).

### Warning
As mentioned previously the WeakRef and Finalizer are **tricky** and are not recommended to be used [WeakRefs TC39 proposal](https://github.com/tc39/proposal-weakrefs).

## Conclusion
JavaScript is an awesome programing language, and that’s something very healthy for web development. Every year there is a new awesome feature that can be used in the project. In this post, we’ve reviewed the **ES2021** features. We expect surprises the next year with a new version **ES2022**

Let me know in your comments recommendations or something else that can be added, I will update the post based on that thanks! 👍

## References
- [WeakRefs TC39 proposal](https://github.com/tc39/proposal-weakrefs)