Back in 2015, the revolutionary ES6 was introduced with a variety of features that are commonly used in modern-day web development.
Since then, ECMAScript has evolved significantly up to ES12, officially known as ECMAScript 2021. ES12 arrived in June 2021 with new capabilities, improvements, and some syntax changes.
Every JavaScript developer eager to perform at their best should learn the latest features of ES12. In this blog, we’ll look into the top six features with examples.
1. Promise.any()
Promise.any() takes an iterable of Promise objects and resolves if any of those promises get resolved. This is useful when we need only one promise to fulfill regardless of what happens to others.
Promise.all() was a similar method that already existed in ES, but it resolved only if all the promises were resolved. Similarly, Promise.race() was used to return the first promise to finish whether it’s resolved or rejected.
const err = new Promise((resolve, reject) => { reject(new Error('Error')); }); const p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('First Promise'); }, 200); }); const p2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Second Promise'); }, 500); }); Promise.any(\\\[err, p1, p2\\\]).then((res) => { console.log(res); }) // output: First Promise
The new AggregateError class help us to catch exceptions of the Promise.any() method. For example, If all the promises passed to Promise.any() are rejected, it will throw an AggregateError object.
const e1 = new Promise((resolve, reject) => { reject(new Error('Error 1')); }); const e2 = new Promise((resolve, reject) => { reject(new Error('Error 2')); }); Promise.any(\\\[e1, e2\\\]) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); // output: "AggregateError: All promises were rejected"
The usage of Promise.any() in development is pretty straightforward. For example, we can send several identical API calls to a server or database and return the data no matter which comes first.
Syncfusion JavaScript UI controls are the developers’ choice to build user-friendly web applications. You deserve them too.
2. WeakRef
As the name suggests, WeakRef is a weak reference to another object. A weakly referenced object will not be kept in memory as long as it is not strongly referenced.
JavaScript uses its garbage collection algorithm to wipe out objects in memory that are no longer referenced by other objects. So, when we create a WeakRef object, it can be garbage collected at any time.
const student = { name: 'John Doe', age: 20, address: { number: 365, street: 'Flower street' } } const ref = new WeakRef(student); ref.deref().age; //output: 20
We can use the deref() method to access the weak reference if it is still available in memory.
Even though WeakRef is useful to save some memory, the authors of WeakRef advise avoiding it at all times if possible, the reason being the complicated behavior of garbage collectors in different JavaScript engines.
3. Private class methods
Since the introduction of classes for JavaScript in ES6, methods and properties have been public by default. Even though developers used the underscore (_) prefix when declaring private methods and properties, it was merely a convention.
It didn’t stop anyone from accessing private properties from outside the class. But with ES12, JavaScript has enabled the creation of private methods and properties natively. To create one, we have to prefix the identifier with a hash (#).
class Auth { #getToken() { return "12345678"; } isAuth() { return this.#getToken(); } } const auth = new Auth(); auth.getToken(); //output: auth.getToken is not a function auth.isAuth(); //output: 12345678
Similar to private methods and properties, we can define private accessors (getters and setters) using the same syntax.
class Auth { get #getToken() { return localStorage.getItem('token'); } set #setToken(token) { localStorage.setItem('token', token); } set login(token) { this.#setToken = token; } get isAuth() { return this.#getToken; } } let token = '12345678'; const auth = new Auth(); auth.login = token; auth.isAuth; //output: 12345678
Every property of the Syncfusion JavaScript controls is completely documented to make it easy to get started.
4. Logical assignment operators
JavaScript already supports arithmetic and bitwise assignment operators. From ES12 onwards, it has extended support to logical assignment operators.
There are three new logical assignment operators:
- Logical Nullish Assignment (??=)
- Logical AND Assignment (&&=)
- Logical OR Assignment (||=)
Even though the syntax looks similar to an arithmetic assignment operator (+=), the logical assignment operators will not always perform the assignment. Instead, the assignment will happen only if the condition defined by the logical operator is met.
4.1 Logical nullish assignment
The logical nullish assignment operator (??=) will assign the value of the right operand to the left operand only if the left operand is null or undefined (nullish).
At first glance, the ??= operator might look a bit confusing because the expanded form of this operator is equivalent to x ?? (x = y).
const person = { name: 'John' }; person.name ??= 'User 1'; console.log(person.name); // output: John person.age ??= 18; console.log(person.age); // output: 18
If we were to use an older ES version, the above code will look like this:
const person = { name: 'John' }; if(person.name === undefined || person.name === null) { person.name = 'User 1'; } console.log(person.name); if(person.age === undefined || person.age === null) { person.age = 18; } console.log(person.age);
4.2 Logical AND assignment
The logical AND assignment operator (&&=) will perform the assignment if the left operand is truthy. Since we just covered the nullish assignment, usage of the logical AND assignment operator is pretty much self-explanatory.
const product = { stocks: 10 }; product.stocks &&= 20; console.log(product.stocks); // output: 20 product.exp &&= '12/31/2021'; console.log(product.exp); // output: undefined
4.3 Logical OR assignment
The logical OR assignment operator (||=) is similar to the nullish assignment, but the left operand should be false for the assignment to occur. A value is considered false if it is null, undefined, false, 0, or NaN.
const product = { stocks: 0, exp: '12/31/2021' }; product.stocks ||= 10; console.log(product.stocks); // output: 10 product.exp ||= '01/31/2022'; console.log(product.exp); // output: 12/31/2021
5. String.replaceAll()
The purpose of the replaceAll() method is to replace all the substrings inside a string. In previous ES versions, if we wanted to do this, we had to use the replace() method.
In the replace() method, only the first occurrence would be replaced if you used a string as the first argument. Therefore, we would set the first argument as a regular expression to replace all the occurrences.
let str = 'hotdog dog'.replace(new RegExp('dog','g'), 'cat'); console.log(str) //output: hotcat cat
With ES12, we can use the replaceAll() method straight away without using regular expressions. This method is super simple and safe.
let str = 'hotdog dog'.replaceAll('dog', 'cat'); console.log(str) //output: hotcat cat
To make it easy for developers to include Syncfusion JavaScript controls in their projects, we have shared some working ones.
6. Numeric separators
This is a simple yet useful feature that was already available in browsers thanks to the V8 engine, but now it comes integrated with ES12. Numeric separators are underscores (_) that help us to separate large numbers.
let billion = 1_000_000_000; console.log(billion); //output: 1000000000
The browser will ignore the underscores. Numeric separators make developers’ lives easier when working with large numbers.
Note: Numbers cannot start or end with a numeric separator, and you can’t use two or more underscores together.
Wrap Up
ECMAScript keeps evolving with the introduction of cool new features every year. The 12th edition of ES has simplified essential coding functionalities with its enhanced features.
In this article, we explored the top six features of ES12 that you should learn as a JavaScript developer. I hope that you take advantage of these features for your development projects.
Thank you for reading!
Syncfusion Essential JS 2 is the only suite you will ever need to build an application. It contains over 65 high-performance, lightweight, modular, and responsive UI components in a single package. Download the free trial to evaluate the controls today.
If you have any questions or comments, you can contact us through our support forums, support portal, or feedback portal. We are always happy to assist you!