ECMAScript 2020 aka ES11

ECMAScript 2020 aka ES11

Overview

ES2020 is the version of ECMAScript corresponding to the yearly release for 2020. In this article, we will see the latest features introduced to JavaScript in ES2020.

Objectives

  1. What is ECMAScript
  2. BigInt
  3. import()
  4. Promise.allSettled()
  5. globalThis
  6. Nullish Coalescing Operator ??
  7. Optional Chaining Operator ?.

Prerequisites

Basic knowledge of JavaScript is helpful to fully understand the new features.

1. What is ECMAScript

JavaScript is a programming language based on the ECMAScript specification. Languages such as ActionScript, JavaScript, JScript, and TypeScript all use ECMAScript as its core. As a comparison, AS/JS/JScript/TS are 4 different cars, but they all use the same engine… each of their exteriors is different though, and there have modifications done to each to make it unique.

History of ECMAScript

Brendan Eich created Mocha which became LiveScript, and later JavaScript. Netscape presented JavaScript to Ecma International which develops standards, and it was renamed to ECMA-262 aka ECMAScript.

It’s important to note that Brendan Eich’s “JavaScript” is not the same JavaScript that is a dialect of ECMAScript. He built the core language which was renamed to ECMAScript, which differs from the JavaScript that browser-vendors implement nowadays.

For more history click here

2. BigInt

BigInt is a built-in object that provides a way to represent whole numbers larger than 2⁵³ — 1, which is the largest number in JS. Javascript can now reliably represent beyond the Number primitive and not just max out at 9007199254740992.

A BigInt is created by adding n to the integer (ex. 5n) or by calling BigInt().

Creating a BigInt

BigInt is similar to Number but is differs in a few ways:

  • It cannot be used with methods in the built-in Math object.
  • BigInt cannot be combined up with an instance of a Number in operations. They can only be used with other BigInt variables unless converted.

Type Checking BigInt

You can check the typeof BigInt like below:

Type Checking

Operators

Operators like + - * ** / can be used with BigInt (or an object wrapped BigInt)

Bitwise operators are supported as well, except >>> (zero-fill right shift) as all BigInts are signed.

Operators

Comparisons

BigInt is not strictly equal to a Number, but it is loosely so:

BigInt Comparisons

Conditionals

A BigInt behaves like a Number in cases where:

  • it is converted to a Boolean
  • when used with logical operators ||, &&, and !
  • within a conditional test like if statement

BigInt Conditional

3. import()

Dynamic import() returns a promise for the module namespace object of the requested module. Therefore, imports can now be assigned to a variable using async/await.

4. Promise.allSettled()

This is another method for promises that checks whether all the promises which we have created have settled

The difference between promise.all() and promise.allSettled() is promise.all() will resolve only if all the promises are resolved successfully and without an error. If any promise gets rejected, .all() won’t resolve. On the other hand, promise.allSettled() will settle even if the promise is resolved or rejected.

Consider the below example. We will create three promises each with a timer and a resolve / reject status, and then we have created Promise.allSettled() in which the last promise gets completed, it will wait.

5. globalThis

Why do we need globalThis since we already have window in the browser?

console.log(window);
console.log(self);
console.log(frames);
console.log(this);

Which will return the same window object

Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}

But if you are using a webworker, only self would work, and if you are using Node.js, they have a separate object called global and you cannot access a window.

To avoid these platform-specific globals, JavaScript decided to add a globalThis which would work in all platforms.

console.log(globalThis);

6. Nullish Coalescing Operator (??)

In JavaScript, we would use objects like below:

const user = {
profile: {
name: 'nidhin',
age: 22
}
}

If we want to print the name then we would like below:

console.log(user.profile.name); // prints value nidhin

But if the property name doesn’t exist.

const user = {
profile: {
age: 22
}
}

And if we try to print the value, it will return undefined. But we can handle this case by giving a value if the property doesn’t exist.

const user = {
profile: {
age: 22
}
}

console.log(user.profile.name || 'kumar');

Which will now return the value kumar since there is no name property. But what if the name property is empty like below example

const user = {
profile: {
name: '',
age: 22
}
}

console.log(user.profile.name || 'kumar');

Now even if it is empty string, JavaScript will consider that it has no value (falsy) and returns the value as kumar.

To avoid it we can use the nullish coalescing operator like below:

console.log(user.profile.name ?? 'kumar');

Which will print the result as an empty string. The nullish operator checks if the property is undefined or null, not for all falsy values. If it is not null or undefined, it will return the initial value else it will print the property value.

7. Optional Chaining Operator (?.)

We will take the same example which we created above:

const user = {
profile: {
name: '',
}
}

Now if I try to print the log as console.log(user.profile.age) it will return undefined since there is no age property, but if I remove the profile property and do the same:

const user = {};
console.log(user.profile.name);

Now it will throw an “error cannot read property name of undefined”. When there are two levels of undefined, JavaScript will throw an error.

Previously in JavaScript, we would check for this situation like below:

console.log(user && user.profile && user.profile.name);

Here we will check whether user property is available. If it is truthy, then we will check profile is available or not.

However, now we can do it much cleaner by using the optional chaining operator like below:

console.log(user?.profile?.name);

Which will return undefined if the property profile or name doesn’t exist. We don’t have to repeat the property name again and again as we did it in the first approach:

console.log(user && user.profile && user.profile.name);
console.log(user?.profile?.name);

Congratulations!

You have learned some of the new features of ES11

Happy Learning :)