Ecma International approves ECMAScript 2022: What’s new?

[2022-06-22] dev, javascript, es2022
(Ad, please don’t block)

On 22 June 2022, the 123nd Ecma General Assembly approved the ECMAScript 2022 language specification, which means that it’s officially a standard now.

This blog post explains what’s new.

The editors of ECMAScript 2022  

The editors of this release are:

What’s new in ECMAScript 2022?  

New members of classes  

class MyClass {
  instancePublicField = 1;
  static staticPublicField = 2;

  #instancePrivateField = 3;
  static #staticPrivateField = 4;

  #nonStaticPrivateMethod() {}
  get #nonStaticPrivateAccessor() {}
  set #nonStaticPrivateAccessor(value) {}

  static #staticPrivateMethod() {}
  static get #staticPrivateAccessor() {}
  static set #staticPrivateAccessor(value) {}

  static {
    // Static initialization block
  }
}

Private slot checks via the in operator  

Private slot checks are also called “ergonomic brand checks for private fields”. The following expression is such a check – it determines if obj has a private slot #privateSlot:

#privateSlot in obj

This is an example:

class ClassWithPrivateSlot {
  #privateSlot = true;
  static hasPrivateSlot(obj) {
    return #privateSlot in obj;
  }
}

const obj1 = new ClassWithPrivateSlot();
assert.equal(
  ClassWithPrivateSlot.hasPrivateSlot(obj1), true
);

const obj2 = {};
assert.equal(
  ClassWithPrivateSlot.hasPrivateSlot(obj2), false
);

Note that we can only refer to a private slot inside the scope in which it was declared.

More information on private slot checks.

Top-level await in modules  

We can now use await at the top levels of modules and don’t have to enter async functions or methods anymore:

// my-module.mjs
const response = await fetch('https://example.com');
const text = await response.text();
console.log(text);

More information on top-level await.

error.cause  

Error and its subclasses now let us specify which error caused the current one:

try {
  // Do something
} catch (otherError) {
  throw new Error('Something went wrong', {cause: otherError});
}

The cause of an error err shows up in the stack trace and can be accessed via err.cause.

More information on error.cause.

Method .at() of indexable values  

Method .at() of indexable values lets us read an element at a given index (like the bracket operator []) and supports negative indices (unlike the bracket operator):

> ['a', 'b', 'c'].at(0)
'a'
> ['a', 'b', 'c'].at(-1)
'c'

The following “indexable” types have method .at():

  • string
  • Array
  • All Typed Array classes: Uint8Array etc.

More information on method .at() of indexable values.

RegExp match indices  

If we add the flag /d to a regular expression, using it produces match objects that record the start and end index of each group capture (lines A and B):

const matchObj = /(a+)(b+)/d.exec('aaaabb');

assert.equal(
  matchObj[1], 'aaaa'
);
assert.deepEqual(
  matchObj.indices[1], [0, 4] // (A)
);

assert.equal(
  matchObj[2], 'bb'
);
assert.deepEqual(
  matchObj.indices[2], [4, 6] // (B)
);

More information on RegExp match indices.

Object.hasOwn(obj, propKey)  

Object.hasOwn(obj, propKey) provides a safe way to check if an object obj has an own (non-inherited) property with the key propKey:

const proto = {
  protoProp: 'protoProp',
};
const obj = {
  __proto__: proto,
  objProp: 'objProp',
}

assert.equal('protoProp' in obj, true); // (A)

assert.equal(Object.hasOwn(obj, 'protoProp'), false); // (B)
assert.equal(Object.hasOwn(proto, 'protoProp'), true); // (C)

Note that in detects inherited properties (line A), while Object.hasOwn() only detects own properties (lines B and C).

More information on Object.hasOwn().

FAQ  

What is the difference between JavaScript and ECMAScript?  

Who designs ECMAScript? TC39 – Ecma Technical Committee 39  

ECMAScript is designed by the Technical Committee 39 (TC39) of the standards organization Ecma International.

Its members are, strictly speaking, companies: Adobe, Apple, Facebook, Google, Microsoft, Mozilla, Opera, Twitter, and others. That is, companies that are usually competitors are working together on JavaScript.

Every two months, TC39 has meetings that member-appointed delegates and invited experts attend. The minutes of those meetings are public in a GitHub repository.

Outside of meetings, TC39 also collaborates with various members and groups of the JavaScript community.

How are features added to ECMAScript? They go through the stages of the TC39 process  

New ECMAScript features must be proposed to TC39. They go through stages:

  • from stage 0 (enables TC39 to comment on a proposal)
  • to stage 4 (the proposed feature is ready to added to ECMAScript)

Once a feature reaches stage 4, it is scheduled to be added to ECMAScript. The feature set of an ECMAScript version is usually frozen in March of each year. Features that reach stage 4 after that deadline are added to next year’s ECMAScript version.

For more information, see section “The TC39 process” in “JavaScript for impatient programmers”.

How important are ECMAScript versions?  

Since the TC39 process was instituted, the importance of ECMAScript versions has much decreased. What really matters now is what stage a proposed feature is in: Once it has reached stage 4, it can be used safely. But even then, you still have to check if the engines you are targeting support it.

How is [my favorite feature proposal] doing?  

If you are wondering what stages various proposed features are in, see the TC39 proposals repository.

Where can I look up which features were added in a given ECMAScript version?  

There are several places where we can look up what’s new in each ECMAScript version:

Free books on JavaScript  

My books on JavaScript are free to read online: