ES2022 Preview - What Are The New Features In ES2022

Introduction

ES2022 JavaScript will be the 13th edition. Several proposed features have moved to Stage 4 of the TC-39 process and those features will be included in ES2022. There are 4 stages in the proposal process, the 4th stage is the last one which makes the proposal finished. In this article, you are going to explore about the upcoming features of the ECMAScript, which have already reached stage 4 and the release as part of ES2022.

New ES2022 Features

The following features are added to JavaScript as part of ES2022. 

  • Array, String, and TypedArray: .at()
  • Error: .cause
  • Private methods and fields,
  • Public static class fields and private static class fields and methods
  • Existence checks for private fields
  • Top-Level await
  • Object: .hasOwn()
  • RegExp: match .indices ('d' flag)

1) Method at() in arrays

In the JavaScript, at() method is used to find an element using index. What is new from this method? In existing JavaScript, we can get the element simply using arr[index]. Then why we need at() method. The reason is, we cannot do arr[-index] to get the element from the ending of the Array. Using of at() method, we can access the element using a positive or negative index of arrays and strings.

const arr = [100,200,300,400, 500];
arr[2];  //200
arr.at(2); //200

arr[arr.length -2]; //400
arr.at(-2); //400

const str = "Test"
str[str.length - 2] // 's'
str.slice(-2)[0]    // 's'
str.at(-2) // 's'

2) Error cause Property

The cause property is added to the Error(). The error cause used to attach the original error to a wrapping error.

const getEmployeeDetail = async (empId) => {
    try {
        return await fetch(`https://api/employee/${empId}`);
    } catch (error) {
        throw new Error(`Loading data Failed for employee id ${empId}.`, {
            cause: error
        });
    }
}
try {
    const employee = await getEmployeeDetail(1);
} catch (error) {
    console.log(error); // Error: Loading data Failed for employee id 1.
    console.log(error.cause); // TypeError: Failed to fetch
}

3) Private Methods and Fields

In ES2022, we will be able to directly declare the private class fields and methods using the # symbol as their prefix.

Private Class Fields

class Employee {
    #name = "Test"; // private field
    setName(name) {
        this.#name = name;
    }
}
const emp = new Employee();
emp.#name = 'New'; // error
emp.setName('New'); // ok

Private Class Methods

class Employee {
    #name = "Test";
    constructor(name) {
        this.#setName(name) // ok
    }
    #setName(name) { // Private method
        this.#name = name;
    }
}
const emp = new Employee('New'); // ok
emp.#setName('New'); // error

4) Public static class fields and private static class fields and methods

A static field or method cannot be accessed in every instance of a class, but only in the prototype. In the ES2022, to define static fields and static public/private methods by using the static keyword.

Prior to ES2022, a class‘s static fields are declared outside of the class body.

class Employee {}
Employee.name = "Test"

In ES2022, the static keyword may be used to specify a class‘s public static fields and private static methods inside of the class body. 

Public Static Fields

class Employee {
    static name = "Test" // Public Static Field
}

Private Static Fields

class Employee {
    static #id = 1; // private static field
    static #getNextId() { // private static method
        return Employee.#id++;
    }
    #id; // instance private
    constructor() {
        this.#id = Employee.#getNextId();
    }
}
const emp = new Employee();
emp.id; // 2

5) Ergonomic Brand Checks for Private Fields

Before ES2022, if we try to access a public field that is not declared we will get an undefined error. If we try to access a private field then, an exception will be thrown. In this case, we could use try/catch inside of a class to check if the private field exists or not. 

In ES2022, we can check whether the private field is present in a specific class or not by using "in" operator. This will also be available for public fields.

class Employee {
    #name = 'Test';
    get #getName() {
        return #name;
    }
    set #setName() {
        #name = 'New';
    }
    static hasName(obj) {
        return #name in obj; // check name property is available or not in the object
    }
}

The "in" keyword will return a boolean value which indicates the presence of a private field. This simple solution does not require a try/catch method or exceptions.

6) Top-level Await

We are using asynchronous functions in JavaScript. Previously, we cannot declare await keyword outside of asynchronous function. But ES2022 allows us to declare the await operator outside of asynchronous functions and classes, which solves the synchronization issue.

It is used to load the modules dynamically

const lang = await import(`/i18n/${navigator.language}`);

It is used to conditionally render modules

const location = "india"

if(location === "india") {
  await require('/data-india.js')
} else {
  await require('/data.js')
}

7) Object.hasOwn(obj, propKey)

It is a static method, used to check that propKey is the own property of object. It is similar to Object.prototype.hasOwnProperty but it supports all object types. 

const example = {
  property: 'Test'
};

console.log(Object.prototype..call(example, 'property')); // old way
console.log(Object.hasOwn(example, 'property')); // new way

8) RegExp Match Indices ('d' Flag) 

If we set the flag /d to regular expressions, we will get the matched strings with an array with starting and ending indexes

To get the list of matches, we can use RegExp.exec or String.matchAll. RegExp.exec will return all of the results one by one and String.matchAll returns an iterator.

const fruits = 'Fruits: apple, applefruit, orange'
const regex = /(apple)/gd;
const matches = [...fruits.matchAll(regex)];
matches[0];

//output:
//[
// "apple",
// "apple",
// groups: undefined
// index: 8
// indices:[]
//  [8, 13],
//  [15, 19]
//]

In the above example, it returned [8,13] means the indices of the first occurrence of "apple" in the input string.

Summary

In this article, you have learned about which new features are coming as a part ES2022 release.