Work Proposals Included in the Coming ECMAScript 2022 Standard for JavaScript


Only ES2021 (or ES12) was released this summer, as many community members have already begun to look into the future, thinking, in particular, what new features ES2022 will bring to us.

This article will introduce and explain some of the proposals that were adopted in the latest draft of the spec.

Each feature proposal must follow a specific scenario, in which it goes through several stages of selection up to the fourth (stage 4), which indicates that this add-on is ready for inclusion in the formal ECMAScript standard and will be available in its next revision. The following features are already ready-made working proposals, which are in the fourth stage and have already been added to latest ECMAScript draft

Class field declarations

Until now in the ES specification, defining and initializing a class field has been done in the class constructor. But thanks to this new proposal, class fields can be defined and initialized at the top level of the class as follows:

class Post{
    title;
    content;
    shares = 0;
}

Private methods and fields

Thanks to this new way of defining class fields, you can now also define private fields – using the # prefix, as shown in the example below:

class User {
    name;
    #password;
}

This also works with declarations of methods and class processors, i.e. methods and processors can also be declared private using the # prefix, as shown below:

class User {
    name;
    #password;
    get #password(){
        return #password;
    }
    #clear(){
        this.name = null;
        this.#password = null;
    }
}

Static public methods and fields

This proposal brings to the specification the functionality of static public fields, static private methods, and static private fields in JavaScript classes, building on the previous proposals. class fields and private methods

This functionality was conceived to cover the “static” aspects of clauses with class fields and private methods, being essentially a logical consequence, as we see in the following example:

class Environment {
    name;
    port;
    static hostname="localhost";
    static get hostname(){
        return hostname;
    }
}

Static methods are usually utility functions, for example, for creating or cloning objects, and static fields are needed when you want a field to exist in a single instance for the entire class, and not in each of its instances that you create. This is useful for caching, committing configuration, or any other data that does not need to be replicated between instances.

Regular expression match indices

This proposal provides a new flag /d to get information about the start and end position for each index of matches found in the input string.

The following code snippet shows how this proposal works:

const regexp = /test(d)/g; //without the /d flag
const regexp2022 = /test(d)/dg; //with the /d flag
const str="test1test2";
const array = [...str.matchAll(regexp)];
const array2022 = [...str.matchAll(regexp2022)];
console.log(array[0]);
console.log(array2022[0]);
console.log(array[1]);
console.log(array2022[1]);

Top-level await

High-level await gives us the ability to use the await keyword outside of asynchronous functions. This proposal allows modules to act like large asynchronous functions, i.e. these ECMAScript modules can wait on resources, so other modules that import them must also wait for them before they start executing their own code.

Note that the following example runs at the top level of the module:

import {getUser} from './data/user'

let user = await getUser();
//

Thanks to this new suggestion, the code above will work without problems, and in the old spec it will output SyntaxError: await is only valid in async function

Ergonomic brand-checking for private fields

When you try to access a public field that is not declared, you simply get undefinedand access to private fields raises an exception. Based on this, we can check if the class has a private field by checking if an exception is thrown when trying to access it. But this proposal provides us with a more elegant solution, which is to use the operator inwhich returns trueif the specified property / field is in the specified object / class, making it work with private fields, as you can see in the following code example:

class User {
    name;
    #password;
    get #password(){
        return #password;
    }
    #clear(){
        this.name = null;
        this.#password = null;
    }
    static hasPassword(obj){
        return #password in obj;
    }
}

New .at () method for all built-in indexable entities

This proposal represents a new method Arrayto get the item at the given index. When we substitute a positive index into this method, it behaves the same as standard parenthetical access, but when we substitute a negative integer index, it works like “negative indexing” in Python, i.e. the countdown will be performed from the last element of the array. Thus, the behavior of the method in this form array.at(-1) will be similar array[array.length-1], which can be seen in the following example:

const array = [0,1,2,3,4,5];

console.log(array[array.length-1]); // 5
console.log(array.at(-1)); //5
//то же поведение

console.log(array[array.lenght-2]); // 4
console.log(array.at(-2)); //4
//то же поведение

Available Object.prototype.hasOwnProperty ()

Sometimes Object.prototype may be unavailable or overridden. For instance, Object.create(null) will create an object that does not inherit from Object.prototype, which will make its methods inaccessible. Also, you cannot be sure that the call .hasOwnProperty() indeed calls an inline method because it can be overwritten if you don’t directly own each property of the object.

To avoid these problems, to call hasOwnProperty() commonly used method call()as shown in the example below:

const obj = { foo:'bar' }
let hasFoo = Object.prototype.hasOwnProperty.call(obj, 'foo');
console.log(hasFoo); //true

This proposal adds the method Object.hasOwn(object, property)which behaves the same as a call Object.prototype.hasOwnProperty.call(object, property)… This new method hasOwn(object, property) provides us with an accessible way to check the properties of an object, more convenient than previous solutions, as you can see below:

const obj = { foo:'bar' }
let hasFoo = Object.hasOwn(obj, 'foo');
console.log(hasFoo); //true

ECMAScript Class Initialization Blocks

This proposal gives us an elegant way to compute blocks of static initialization of code when declaring / defining a class with access to its private fields.

The current proposals for static and static private fields provide a mechanism for performing the initialization of the static portion of a class on each field during ClassDefinitionEvaluationhowever there are some cases that are so easy to implement. For example, if you need to evaluate operators during initialization (for example, try..catch) or set two fields from the same value, you must execute this logic outside of the class definition.

This can be understood by the following example:

No static blocks:

class User {
    static roles;
    name;
    #password;
}

try { 
    User.roles = getRolesFromDb();
} catch { 
    User.roles = getRolesFromBackup();
}

With static blocks:

class User {
    static roles;
    name;
    #password;
    static {
        try { 
            User.roles = getRolesFromDb();
        } catch { 
            User.roles = getRolesFromBackup();
        }
    }
}

As you can see in this example, there is not much difference between the two solutions, since the static block is quite simple and small. However, if you do not use static blocks, then as the complexity of the block of code grows, these types of initialization will be less elegant, visual, and readable.

That’s all, if you have any doubts or suggestions about this, please let me know.

Also, hello!

Links and additional information:


The material was prepared within the framework of the specialization “Fullstack Developer”

We invite everyone to a free demo lesson “Such different numbers!“. The lesson will cover such data types in JavaScript as number and bigint, as well as the peculiarities of their structure and operations with them.
>> REGISTRATION

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *