DEV Community

Cover image for New JavaScript Features ECMAScript 2021 (with examples)
Brayan Arrieta
Brayan Arrieta

Posted on • Updated on

New JavaScript Features ECMAScript 2021 (with examples)

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

// 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
Enter fullscreen mode Exit fullscreen mode

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)

const message = 'hello+this+is+a+message';
const messageWithSpace = message.replace(/\+/g, ' ');

// hello this is a message
Enter fullscreen mode Exit fullscreen mode

After (with new method replaceAll)

const message = 'hello+this+is+a+message';
const messageWithSpace = message.replaceAll('+', ' ')

// hello this is a message
Enter fullscreen mode Exit fullscreen mode

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

let a = 1;
if(a){
  a = 8;
}

// Output: a = 8
Enter fullscreen mode Exit fullscreen mode

After

let a = 1;
a &&= 3

// Output: a = 3
Enter fullscreen mode Exit fullscreen mode

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

// If conditional
let a = undefined;
if(!a){
  a = 5;
}

// Output: a = 5

// OR
a = a || 3;

// Output: a = 3
Enter fullscreen mode Exit fullscreen mode

After

let a = 0;
a ||= 3

// Output: a = 3
Enter fullscreen mode Exit fullscreen mode

Nullish Coalescing & Equals (??=)

Assign when the value is null or undefined.


let a = undefined; 
a ??= 7

// Output: a = 7
Enter fullscreen mode Exit fullscreen mode

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

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
}
Enter fullscreen mode Exit fullscreen mode

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

const objectExample = {name: "Juanito", lastname: "Jordan"};
const refObj = new WeakRef(objectExample);
Enter fullscreen mode Exit fullscreen mode

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

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

// Output: 'Juanito'
Enter fullscreen mode Exit fullscreen mode

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

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

const registry = new FinalizationRegistry(value => {
  // Do some stuff
});
Enter fullscreen mode Exit fullscreen mode

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.

registry.register({greeting: "Hello World"}, "greetingObject");
Enter fullscreen mode Exit fullscreen mode

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.

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

Oldest comments (5)

Collapse
 
kerryboyko profile image
Kerry Boyko

No mention of Tuples and Records? github.com/tc39/proposal-record-tuple

const tuple = #['string', Math.PI];
const record = #{foo: 'bar'};

Collapse
 
brayanarrieta profile image
Brayan Arrieta

I will check thx 👌

Collapse
 
andreasanta profile image
Andrea S.

They're just immutable versions of arrays and objects, right?

Collapse
 
nikhilroy2 profile image
Nikhil Chandra Roy

great

Collapse
 
jialihan profile image
jialihan

does the private method & private field already exist before ES2021?