This page looks best with JavaScript enabled

JavaScript ES2020 Features You Should Know

 ·  ☕ 6 min read  ·  ✍️ Adesh

Optional Chaining

The optional chaining ?. is an error-proof way to access nested object properties, even if an intermediate property doesn’t exist. Optional chaining syntax allows you to access deeply nested object properties without worrying if the property exists or not. If it exists, great! If not, undefined will be returned.

Here is the example of one of most common error caused due to accessing non-exist property of an object.

TypeError: Cannot read property ‘x’ of undefined

Let’s see how optional chaining can rescue us to get avoid this error.

Optional Chaining With Missing Object Property

1
2
3
4
5
6
7
const person = {
    firstname: 'fname',
    lastname: 'lname'
}

console.log(person.firstname);  // ok
console.log(person.address.city); // error: Uncaught TypeError: Cannot read property 'city' of undefined

You will get an error while trying to read the non-existence city property of a person object. Using optional chaining (?.) will prevent this error and output the undefined value.

console.log(person.address?.city); // undefined

Optional Chaining With an Empty Or Null Array

When you try to access an element of an empty or null array, it will throw an exception.

1
2
3
4
5
6
7
person =  null;

console.log(person[0]); // error: Uncaught TypeError: Cannot read property '0' of null
// or

person = ['adam', 'robert'];
console.log(person[2]); // error: Uncaught TypeError: Cannot read property '0' of null

Now, use optional chaining to prevent this error.

1
2
3
4
5
6
7
person =  null;

console.log(person?.[0]); // undefined
// or

person = ['adam', 'robert'];
console.log(person?.[2]); // undefined

Optional Chaining With an Missing function

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
let func = () => {
  return 'function call'
}

console.log(func()) // function call

func = null

console.log(func()) // error: Uncaught TypeError: func is not a function

console.log(func?.()) // undefined

When we try to access a function which is null, it will throw an exception. Optional chaining will prevent this error and return an undefined value here.

Nullish Coalescing

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.

Contrary to the logical OR (||) operator, the left operand is returned if it is a falsy value which is not null or undefined. In other words, if you use || to provide some default value to another variable foo, you may encounter unexpected behaviors if you consider some falsy values as usable (eg. '' or 0). See below for more examples.

1
2
3
4
5
6
7
const foo = null ?? 'default string';
console.log(foo);
// expected output: "default string"

const baz = 0 ?? 42;
console.log(baz);
// expected output: 0

In this example, we will provide default values but keep values other than null or undefined.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const nullValue = null;
const emptyText = ""; // falsy
const someNumber = 42;

const valA = nullValue ?? "default for A";
const valB = emptyText ?? "default for B";
const valC = someNumber ?? 0;

console.log(valA); // "default for A"
console.log(valB); // "" (as the empty string is not null or undefined)
console.log(valC); // 42

BigInt

BigInt can be used to represent whole numbers larger than 253 - 1. BigInt can be used for arbitrarily large integers.

A bigint is created by appending n to the end of an integer literal or by calling the function BigInt that creates bigints from strings, numbers etc.

1
2
3
const bigInt = 1234567890123456789012345678901234567890n;

const bigIntFromNumber = BigInt(10); // same as 10n

Dynamic Import

Dynamic imports in JavaScript give you the option to import JS files dynamically as modules in your application natively. 

This feature will help you ship on-demand-request code, better known as code splitting, without the overhead of webpack or other module bundlers. You can also conditionally load code in an if-else block if you like.

1
2
3
4
if(condition) {
  const mathModule = await import('./dynamicModule.js');
  mathModule.sum(10, 20);
}

Private Field

One of the main purposes of classes is to contain our code into more reusable modules. Because you’ll create a class that’s used in many different places you may not want everything inside it to be available globally.

Now, by adding a simple hash symbol in front of our variable or function we can reserve them entirely for internal use inside the class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Message {
  #message = "ZeptoBook"

  greet() { console.log(this.#message) }
}

const greeting = new Message()

greeting.greet() // ZeptoBook
console.log(greeting.#message) // Private name #message is not defined

Promise.allSettled

To wait for multiple promises to finish, Promise.all([promise_1, promise_2]) can be used. The problem is that if one of them fails, then an error will be thrown. Nevertheless, there are cases in which it is ok for one of the promises to fail, and the rest should still resolve. To achieve that, ES11 introduced Promise.allSettled.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const p1 = new Promise((res, rej) => setTimeout(res, 1000));

const p2 = new Promise((res, rej) => setTimeout(rej, 1000));

Promise.allSettled([p1, p2]).then(data => console.log(data));

// [
//   Object { status: "fulfilled", value: undefined},
//   Object { status: "rejected", reason: undefined}
// ]

MatchAll

matchAll is a new method added to the String prototype which is related to Regular Expressions. This returns an iterator which returns all matched groups one after another.

Javascipt match all

globalThis

Historically, accessing the global object has required different syntax in different JavaScript environments. On the web you can use windowself, or frames - but in Web Workers only self will work. In Node.js none of these work, and you must instead use global.
The this keyword could be used inside functions running in non–strict mode, but this will be undefined in Modules and inside functions running in strict mode. You can also use Function('return this')(), but environments that disable eval(), like CSP in browsers, prevent use of Function in this way.

The globalThis property provides a standard way of accessing the global this value (and hence the global object itself) across environments. Unlike similar properties such as window and self, it’s guaranteed to work in window and non-window contexts. In this way, you can access the global object in a consistent manner without having to know which environment the code is being run in.To help you remember the name, just remember that in global scope the this value is globalThis.

Static Fields

Static fields in classes is a new feature that’s coming soon to browsers and Node.js. It lets us add static fields for classes that do not need an instance of the class to be created to be accessed. They can both be private or public. It’s a handy replacement for enums.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Person {  
  static age = 25;
  static firstname = 'fname';
  static lname = 'lname';
  static city = 'jersey city';
  
}
console.log(Person.age);
console.log(Person.firstname);
console.log(Person.lname);
console.log(Person.city);

Summary

I hope you found this article useful and are as excited as I am about the new features that are coming to JavaScript. 

Further Reading

Learn about module design pattern in JavaScript

Understand Shallow And Deep Copy In JavaScript

Object Mutation In JavaScript

Share on

Adesh
WRITTEN BY
Adesh
Technical Architect