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 this release are:
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
}
}
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.
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
.
.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
Uint8Array
etc.More information on method .at()
of indexable values.
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()
.
Short version – colloquially:
For the long version, see section “Standardizing JavaScript” in “JavaScript for impatient programmers”.
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.
New ECMAScript features must be proposed to TC39. They go through stages:
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”.
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.
If you are wondering what stages various proposed features are in, see the TC39 proposals repository.
There are several places where we can look up what’s new in each ECMAScript version:
In “JavaScript for impatient programmers”, there is a section that lists what’s new in each ECMAScript version. It also links to explanations.
The TC39 repository has a table with finished proposals that states in which ECMAScript versions they were (or will be) introduced.
Section “Introduction” of the ECMAScript language specification lists the new features of each ECMAScript version.
The ECMA-262 repository has a page with releases.
My books on JavaScript are free to read online:
“JavaScript for impatient programmers (ES2022 edition)” covers JavaScript up to and including ECMAScript 2022.
“Deep JavaScript: Theory and techniques” covers language foundations in more depth.