ES2021 is the 12th ECMAScript version approved by the TC39 committee. It includes some exciting features every JavaScript developer should know. So, in this article, I will discuss some of the highlights of ES2021 to give you a better understanding.
Promise.any
The promise.all() was introduced with ES2020 to run multiple promises concurrently and act when they were all settled (fulfilled or rejected). With ES2021, Promise.any() was introduced, which can handle an array of promises.
The Promise.any() method takes a list of promises and returns the value of the first promise that is resolved. In the following example, we pass two promises to the Promise.any() method, and it will give an output as soon as the first promise is resolved, since it has the minimum waiting time.
// When all the promises are passed. const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 10000, "100 second"); }); const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 20000, "200 second"); }); let promises = [promise1, promise2]; Promise.any(promises).then((value) => { console.log(value); // outputs “100 second” })
If none of the queued promises resolves, the Promise.any() will return a rejected promise returning an AggregateError, a collection of all errors found.
// When all the promises are rejected. const promise1 = new Promise((resolve, reject) => { setTimeout(reject, 1000, "100 second"); }); const promise2 = new Promise((resolve, reject) => { setTimeout(reject, 2000, "200 second"); }); let promises = [promise1, promise2]; Promise.any(promises).then((value) => { console.log(value); }).catch((err) => { console.log("error: " + err) }) // outputs error: AggregateError: All promises were rejected
AggregateError
AggregateError is an error subclass that combines multiple errors into a single object.
// Syntax AggregateError(Array<Error>, “message”);
An AggregateError is generated if all promises are passed to promise.any() fail, following a message describing the error.
// Creating an AggregateError. try { throw new AggregateError( [new Error("an error"), new TypeError("Typeof error for some field")], "common error message"); } catch (e) { console.log(e instanceof AggregateError); // true console.log(e.message); // "common erro message" console.log(e.name); //"AggregateError" console.log(e.errors); //[ Error: "an error", TypeError: Typeof error for some field] }
As shown, AggregateError allows you to retrieve the promise messages that contributed to the error using AggregateError.errors.
WeakRef and Finalizers
WeakRef stands for weak references. Weak references commonly help us to build caches or mappings to larger objects. A WeakRef creates a weak reference to the object passed to it. Since a WeakRef variable is the only reference to an object, the JavaScript engine can safely remove it from memory and free up space when the browser does garbage collection.
Refer to the following code.
//WeakRef variable value can be accessed via the deRef method. const weakRef = new WeakRef({ age: 13; }); console.log(weakRef.deref().age) // output: 13
Note: Please avoid using WeakRef as much as possible since it does not have a guaranteed behavior.
WeakRef and finalizers are two features that go together. The FinalizationRegistry method allows you to request a callback after an object has become unreachable (garbage-collected).
First, define a registry with the callback you want to run. Then, call the .register method on the defined registry with the object you want to observe. It will let you know exactly when the memory of the object is freed by the garbage collector.
Refer to the following code.
const registry = new FinalizationRegistry(value => { console.log("Finalizer"); }); registry.register({object: "Do Something"}, "testObject");
Here, the object passed to the register() method is weakly referenced, so when the value is garbage collected, the second parameter is passed to the finalizer (testObject).
Numeric separators
This new feature allows you to use underscores as separators for the numeric literals. It increases the readability of the numbers by separating groupings of numbers visually.
Refer to the following example.
// A billion const amount = 1000000000; // Previous const amount = 1_000_000_000; // With ES2021 // Hundreds of millions const amount = 1475938.38; // Previous const amount = 1_475_938.38; // With ES2021
This is much easier to read now. This does not affect performance or equality. 1000000000 is still equal to 1_000_000_000.
String.protype.replaceAll
The replaceAll method replaces all pattern occurrences with the replacement passed to it. The pattern parameter can be a string or a regex pattern, and the replacement parameter can be either a string or a function.
The replaceAll method is an improvement to the String.replace method, which can only replace the first occurrence of the pattern.
Before
const message = 'hello+good+morning'; const messageWithSpace = message.replace(/\+/g, ' '); // hello good+morning
After (with method replaceAll)
const message = 'hello+good+morning'; const messageWithSpace = message.replaceAll('+', ' ') // hello good morning
Logical Assignment Operators
Three new logical assignment operators were introduced in the ECMAScript 2021 update. These operators are pretty similar to the existing logical operators, and they help assign values to variables in a single line.
- Logical OR assignment operator ||=
- Logical AND assignment operator &&=
- Logical nullish assignment operator (??=)
Logical OR assignment operator (||=)
p ||= q // This is exactly identical to the below expression. if (!p) { p = q } // If p is false, q will be assigned to it. Otherwise, p is left at its original value.
Logical AND assignment operator (&&=)
p &&= q // This is exactly identical to the below expression. if (p) { p = q } // If p is true, q will be assigned to it. Otherwise, p is left at its original value.
Logical nullish assignment operator (??=)
x ??= y
This only assigns y to x if x is either null or undefined.
Private Accessors
Private accessors work very similarly to private methods. So, let’s create a simple class with a private method to understand the difference.
Previous versions
class ExampleClass { MyMethod1() { console.log("Public method") } #MyMethod2() { console.log("Hidden method") } } const exampleClass= new ExampleClass () exampleClass.MyMethod1() exampleClass.MyMethod2() // output // Public method // exampleClass.MyMethod2 is not a function.
In the previous ECMAScript versions, we can’t call MyMethod2(), since it is a private method. If you run the previous code, it will give an error saying that the exampleClass.MyMethod2 is not a function.
With ES2021
With the ES2021 updates, we can create a new public method called inside the class (callAll() ), and access the private method.
class ExampleClass { MyMethod1() { console.log("Public method") } #MyMethod2() { console.log("Hidden method") } callAll() { this.MyMethod1() this.#MyMethod2(); } } const exampleClass = new ExampleClass() exampleClass.callAll(); // output // Public method // Hidden method
Like private methods, we can now define getters and setters in JavaScript, making them only accessible inside a class or by an instance created.
class ExampleClass { get #Greeting() {return "Hello Good Morning !" } get viewGreetingMsg() { return this.#Greeting } } let exampleClass = new ExampleClass(); console.log(exampleClass.viewGreetingMsg); // Hello Good Morning !
dateStyle and timeStyle options for Intl.DateTimeFormat
The Intl.DateTimeFormat can enable language-sensitive date and time formatting. The proposed dateStyle and timeStyle options allow us to request a locale-specific date and time of a given length.
// Time with short format let. let time = new Intl.DateTimeFormat('en' , { timeStyle: 'short' }); console.log(time .format(Date.now())); // 09:27 PM // Time with medium format. let time = new Intl.DateTimeFormat('en' , { timeStyle: 'medium'}); console.log(time .format(Date.now())); //09:27:50 PM // Time with long format. let time = new Intl.DateTimeFormat('en' , { timeStyle: 'long' }) ; console.log(time .format(Date.now())); // 11:27:50 PM GMT+11
Conclusion
In this article, I discussed the top eight highlights of the ES2021 update. I hope this article helped you to improve your JavaScript knowledge. Thank you for reading.
Syncfusion Essential JS 2 is the only suite you will ever need to build an app. It contains over 65 high-performance, lightweight, modular, and responsive UI components in a single package. Download a free trial to evaluate the controls today.
If you have any questions or comments, you can also contact us through our support forums, support portal, or feedback portal. We are always happy to assist you!