New Features in ECMAScript 2021 (with code examples)
Tags: javascript, tutorial, webdev, frontend
Published: 2021-03-09 10:08:53

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qakqanq79z8exo4pu63y.jpg)

In this tutorial we are going to learn about the new features we can use in the latest version of ECMAScript 2021 with some coding examples

#Introduction

This Ecma Standard defines the ECMAScript 2022 Language. It is the twelfth edition of the ECMAScript Language Specification. Since publication of the first edition in 1997, ECMAScript has grown to be one of the world's most widely used general-purpose programming languages. It is best known as the language embedded in web browsers but has also been widely adopted for server and embedded applications.Introduction
This Ecma Standard defines the ECMAScript 2022 Language. It is the twelfth edition of the ECMAScript Language Specification. Since publication of the first edition in 1997, ECMAScript has grown to be one of the world's most widely used general-purpose programming languages. It is best known as the language embedded in web browsers but has also been widely adopted for server and embedded applications.

#ECMA 2021

ECMAScript 2021, the 12th edition, introduces the `replaceAll` method for Strings; `Promise.any`, a Promise combinator that short-circuits when an input value is fulfilled; `AggregateError`, a new Error type to represent multiple errors at once; logical assignment operators (`??=`, `&&=`, `||=`); `WeakRef`, for referring to a target object without preserving it from garbage collection, and `FinalizationRegistry`, to manage registration and unregistration of cleanup operations performed when target objects are garbage collected; separators for numeric literals (`1_000`); and `Array.prototype.sort` was made stable.


##replaceAll

Assuming we have a constant named string

```javascript
const string = "Javascript is the best web scripting language. Javascript can be used for both front end and backend";
```

and we want to replace the word  `Javascript`   with  `Typescript` 
we normally would use the ` replace` method

```javascript
const string = "Javascript is the best web scripting language. Javascript can be used for both front end and backend";

console.log(string.replace("Javascript", "Typescript"));
```
What if we want to replace all instances of `Javascript` with `Typescript`
That is where the replaceAll method comes to shine

```javascript
const string = "Javascript is the best web scripting language. Javascript can be used for both front end and backend";

console.log(string.replaceAll("Javascript", "Typescript"));
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hsxj4bwxjfrhn2qc6c6n.png)

##Private Methods

lets create a class named `People` and we have will have some methods 
```javascript
class People {
  showName() {
    console.log("My name is Faithful")
  }
  showAge() {
    console.log("Faithful is 20")
  }
}
```
To access the methods inside the classes we first need to instantiate the class

```javascript
class People {
  showName() {
    console.log("My name is Faithful")
  }
  showAge() {
    console.log("Faithful is 20")
  }
}

const people = new People()

people.showName()
people.showAge()
```
We can see that `My name is Faithful` and `Faithful is 20` gets logged on console.

if we want to make showAge() a private method inside the class People so outside the scope of the class it is not accessible
we just add the `#` sign in front of the `showAge` method like this `#showAge`

```javascript
class People {
  showName() {
    console.log("My name is Faithful")
  }
  #showAge() {
    console.log("Faithful is 20")
  }
}

const people = new People()

people.showName()
people.showAge() 
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ozcoj8ljvqavm8t9fmn5.png)
we can see the result on our console. An error is saying  `people.showAge` is not a function. This is because `#showAge()` is now a private method inside the class People and can only be access via a public method in side the class People.

Now lets try and access the private method `#showAge()`

first we create new public method called `showAll()` inside the class People from this public method we can access the private method `#showAge()` and since our new method is a public one we would be able to print the age on the console. Take a look at the code below
```javascript
class People {
  showName() {
    console.log("My name is Faithful");
  }
  #showAge() {
    console.log("Faithful is 20");
  }
  showAll() {
    this.showName()
    this.#showAge();
  }
}

const people = new People();
people.showAll();
```
we can see that the error has disappeared and we can now access our private method via a public one `showAll()`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i5ofvl2h509kuqjrddne.png)

##Private Accessors

Private accessors work very similar to private methods lets create a class named `People` and we have will have some methods 
```javascript
class People {
  get Name() {
    return "Faithful"
  }
  get Age() {
    return 20
  }
}

let people = new People();
console.log(people.Age);
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s4vq8o2h4evk7fw7ygst.png)
We can see `20` gets logged on console.

if we want to make Age a private accessor inside the class People so outside the scope of the class it is not accessible
we just add the `#` sign in front of the `Age` method like this `#Age`

```javascript
class People {
  get Name() {
    return "Faithful"
  }
  get #Age() {
    return 20
  }

}

let people = new People();
console.log(people.Age) 
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oda8qjvim0y5guwvhrg2.png)
we can see the result on our console is undefined.
Now lets try and access the private method `#Age()`

first we create new public method called `publicAge()` inside the class People from this public method we can access the private method `#Age()` and since our new method is a public one we would be able to print the age on the console. Take a look at the code below
```javascript
class People {
  get Name() {
    return "Faithful"
  }
  get #Age() {
    return 20
  }
  get publicAge() {
    return this.#Age
  }
}

let people = new People();
console.log(people.publicAge)
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zonr05rjy5po7p8jdtw.png)
we can see that the error has disappeared and we can now access our private accessor via a public one `publicAge()`


##Promise.any()
**Promise.any()** is like the opposite of `Promise.all()`. Promise.any() resolves if any of the supplied promised is resolved unlike `promise.all()` which waits for all promises to resolve before it resolves.
lets take a look at the example below
Basically we have 3 promises that resolves at random times. We have used `setTimeout()` function to set a time taken for each promise to resolve and we used Math.floor(Math.random) to give a random time to the setTimeout function so we really dont know which promise resolves first. This exaclty what happens in real world secenario.
```javascript
const prom1 = new Promise((resolve, reject) => {
  setTimeout(
    () => resolve("this is the first promise"),
    Math.floor(Math.random() * 100)
  );
});
const prom2 = new Promise((resolve, reject) => {
  setTimeout(
    () => resolve("this is the second promise"),
    Math.floor(Math.random() * 100)
  );
});
const prom3 = new Promise((resolve, reject) => {
  setTimeout(
    () => resolve("this is the third promise"),
    Math.floor(Math.random() * 100)
  );
});

(async function() {
  const result = await Promise.any([prom1, prom2, prom3]);
  console.log(result); // Prints "A", "B" or "C"
})();
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vb51zvelwyq3mzjtr7ml.png)
from the result in console, we can see that our second promise resolves first.


**Wait!** what if none of the promises resolve? Well, Promise.any() throws an AggregateError exception. We will handle it in a try catch block.
Take a look at the example below
```javascript
const rejected = new Promise((resolve, reject) => {
  setTimeout(
    () => reject("this is the first promise"),
    Math.floor(Math.random() * 100)
  );
});

try {
  (async function() {
    const result = await Promise.any([rejected]);
    console.log(result);
  })();
} catch(error) {
  console.log(error.errors);
}
```

##Numeric Separators
This feature enables developers to make their numeric literals more readable by creating a visual separation between groups of digits. Large numeric literals are difficult for the human eye to parse quickly, especially when there are long digit repetitions.

```
1000000000   // Is this a billion? a hundred millions? Ten millions?
101475938.38 // what scale is this? what power of 10?
```
###Examples
**Regular Number Literals**
```javascript
let budget = 1_000_000_000_000;
// What is the value of `budget`? It's 1 trillion!
// 
// Let's confirm:
console.log(budget === 10 ** 12); // true
```
**Binary Literals**
```javascript
let nibbles = 0b1010_0001_1000_0101;
// Is bit 7 on? It sure is!
// 0b1010_0001_1000_0101
//          
// We can double check: 
console.log(!!(nibbles & (1 << 7))); // true
```
**Hex Literals**
```javascript
// Messages are sent as 24 bit values, but should be 
// treated as 3 distinct bytes:
let message = 0xA0_B0_C0;

// What's the value of the upper most byte? It's A0, or 160.
// We can confirm that:
let a = (message >> 16) & 0xFF; 
console.log(a.toString(16), a); // a0, 160

// What's the value of the middle byte? It's B0, or 176.
// Let's just make sure...
let b = (message >> 8) & 0xFF;
console.log(b.toString(16), b); // b0, 176

// What's the value of the lower most byte? It's C0, or 192.
// Again, let's prove that:
let c = message & 0xFF;
console.log(c.toString(16), b); // c0, 192
```
lets view our result in console
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lsb5ml79xx56ybzom9z7.png)

##Logical Assignment Operator
####Logical Assignment Operator with  `&&`
Logical assignment operator combines the logical operations(&&, || or ??) with assignment.
```javascript
var x = 1;
var y = 2;
x &&= y;
console.log(x); // 2
```
Techincally here's what is actually going on 
```
if(x) {
  x = y
}
```
Since `x` is a truthy value, it is assigned with the value of `y`, ie `2`.

Just like the way we did with `&&`, we can do with `||` and `??`.
```
x &&= y;
x ||= y;
x ??= y;
```
####Logical assignment operator with `||`
```javascript
var x = 1;
var y = 2;
x ||= y;
console.log(x);
```
That means, the assignment operation happens only if `x` is a falsy value. In our code, `x` contains `1` which is a truthy value and hence, assignment does not happen. That is why our code prints `1` in the console.

####Logical assignment operator with `??`
`??` is Nullish Coalescing operator in JavaScript. It specifically checks if a value is `null` or `undefined`.
```javascript
var a;
var b = a ?? 5;
console.log(b);
```
In line 2, if the value of `a` is `null` or `undefined`, the right hand side of `??` is evaluated and assigned to `b`.

Let us now consider `??` along with `=`.
```javascript
var x;
var y = 2;
x ??= y;
console.log(x); // 
```
Here the value of `x` is `undefined`. So the right hand side expression is evaluated and sets `x` to `2`.

##You can edit and test the code here
{% stackblitz ecma2021-newfeatures %}

#Happy Coding!