catalins.tech with Gatsby

ES2020 – My Favourite Features From ES2020

2020 Jun 5th

ES2020 or ECMAScript 2020 brings exciting features to JavaScript. In this article, I want to talk about my favourite features from ES2020. As a result, this article does not cover all the features from ES2020. So what are my favourite new additions?

  1. Dynamic Import
  2. Nullish Coalescing Operator
  3. Optional Chaining Operator
  4. Private Class Variables
  5. Promise.allSettled

For more information, have a look at the official ECMAScript Language Specification. On the same note, you can have a look at the finished proposals. So let us see the new features in action.

DYNAMIC IMPORTS

One of the coolest additions is that we can import dependencies dynamically with async/await. That means we can import these dependencies only when we need them. As a result, the performance of the application improves by loading the modules at runtime.

How does it improve performance? With the conventional module system, we import the modules statically at the beginning of the program. Whether we need them now or later, we have to import them first. Also, all the code from an imported module is evaluated at the load time. Thus, it slows down the application. Why? Because it downloads the imported modules and evaluates the code of each module before executing your code.

Ok, ok. Enough talk. Let us see some examples. 

if (car) {
    const cars = await import('./cars.js');
    
    const carList = cars.loadList();
    
    console.log(carList);
}

Above you can see a basic example of dynamically importing a module. From now on, we do not have to waste resources by importing all the modules first. We can import them dynamically when we need them. I love this new feature.

NULLISH COALESCING OPERATOR

“The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.” (Source: MDN)

Below you can see examples of the nullish coalescing operator in action. 

const person = {
  name: "Catalin Pit",
  socialMedia: {
    twitter: "@catalinmpit",
    instagram: "@catalinmpit",
    linkedin: "@catalinmpit",
  },
  experience: "Junior",
  employed: true
};

console.log(person.socialMedia.facebook ?? 'No Facebook account found!'); // Outputs 'No Facebook account found!'
console.log(person.socialMedia.instagram ?? 'No Instagram account found!'); // Outputs '@catalinmpit'


/// Another example ///
let name;

console.log(name ?? 'No name assigned'); // Outputs 'No name assigned'

name = 'Catalin Pit';

console.log(name ?? 'No name assigned'); // Outputs 'Catalin Pit'

What is the difference between double pipes “||” and this operator? When using the double pipes “||”, it always returns a truthy value which might lead to some unexpected results. When using the nullish coalescing operator, we can be more strict and thus only allow the default when the value is null or undefined. 

For example, let us say we have the following code:

let shoeSize = 0;

console.log(shoeSize ?? 40); // returns 0
console.log(shoeSize || 40); // returns 40

In the above example, the value 0 is treated as a falsy value when using the pipes. On the other hand, the value 40 is returned when the value of shoeSize is null or undefined. Therefore, the double question mark allows us to check if a variable is nullish, which means if a variable is either undefined or null. 

OPTIONAL CHAINING OPERATOR

“Shorter and simpler expressions when accessing chained properties when the possibility exists that a reference may be missing.” (Source: MDN)

Another feature from ES2020 that I love is the optional chaining operator. Using this operator, we can access deeply nested properties from an object, as shown in the example below. If the property exists, that is what the operator returns. If the property does not exist, the operator returns undefined.

const person = {
  name: "Catalin Pit",
  socialMedia: {
    twitter: "@catalinmpit",
    instagram: "@catalinmpit",
    linkedin: "@catalinmpit",
  },
  experience: "Junior",
  employed: true
};

if (person && person.socialMedia && person.socialMedia.twitter) {
  console.log(person.socialMedia.twitter);
}

// The same thing with optional chaining
if (person?.socialMedia?.twitter) {
  console.log(person.socialMedia.twitter); // outputs @catalinmpit
}

// or
console.log(person?.socialMedia?.twitter);

Moreover, you can use this operator on function calls and arrays too. The example above only shows the use of this operator on an object. You can see the benefits straightway by comparing lines 12-13 with line 22. It makes the code shorter and more readable.

PROMISE.ALLSETTLED

The new method, Promise.allSettled() waits for all promises to be settled. That is, it takes an array of Promises, and it only returns when the promises are settled, either rejected or resolved. 

When this function returns, we can loop over each Promise and see whether it was fulfilled or rejected, and why.  Let us see an example of this function in action.

const promisesArray = [fetch("/users"), fetch("/teams"), fetch("/matches")];

Promise.allSettled(promisesArray).then(result => console.log(result));

The above code returns an array of objects, with each object representing a Promise. Each object has a status and a value if the Promise is fulfilled, or a status and a reason if the Promise is rejected. 

I love this feature because it makes it easier to work with multiple Promises.

PRIVATE CLASS VARIABLES

From now on, we can create private variables in classes. All you need to do to create a private variable is to add the hash symbol in front of the variable. 

Trying to call the variable outside of the class, results in a SyntaxError. It says that you need to declare the variable in an enclosing class.

class Person {
    #fullName = "Catalin Pit";
    
    sayMyName() {
        console.log(`My name is ${this.#fullName}`);
    }
}

const person1 = new Person();
person1.sayMyName(); // Returns "MY names is Catalin Pit"
person1.#fullName; // Returns "Uncaught SyntaxError: Private field '#fullName' must be declared in an enclosing class"
person1.fullName; // Returns "undefined"

In the code above, you can see a private class variable in action. Trying to access it outside the class, we get an error. I think this feature is pretty cool and useful.

CONCLUSION

Dynamic Imports, Nullish Coalescing Operator, Optional Chaining Operator, Private Class Variables and Promise.allSettled are my favourite features from ES2020/ECMAScript2020/ES11. I encourage you to play around with the code snippets to understand them better.

Also, remember that the features from this article are not all the features from ES2020. To read about all the features, have a look at the links from the beginning of the article. 

Check some of the articles I published recently: