On 26 June 2024, the 127th Ecma General Assembly approved the ECMAScript 2024 language specification, which means that it’s officially a standard now.
This blog post explains what’s new.
The editors of this release are:
Map.groupBy()
groups the items of an iterable into Map entries whose keys are provided by a callback:
assert.deepEqual(
Map.groupBy([0, -5, 3, -4, 8, 9], x => Math.sign(x)),
new Map()
.set(0, [0])
.set(-1, [-5,-4])
.set(1, [3,8,9])
);
There is also Object.groupBy()
which produces an object instead of a Map:
assert.deepEqual(
Object.groupBy([0, -5, 3, -4, 8, 9], x => Math.sign(x)),
{
'0': [0],
'-1': [-5,-4],
'1': [3,8,9],
__proto__: null,
}
);
For tips on choosing between these two methods and more examples, see “Exploring JavaScript”.
Promise.withResolvers()
Promise.withResolvers()
provides a new way of creating Promises that we want to resolve:
const { promise, resolve, reject } = Promise.withResolvers();
/v
The new regular expression flag /v
(.unicodeSets
) enables these features:
Escapes for Unicode string properties (😵💫 consists of three code points):
// Previously: Unicode code point property `Emoji` via /u
assert.equal(
/^\p{Emoji}$/u.test('😵💫'), false
);
// New: Unicode string property `RGI_Emoji` via /v
assert.equal(
/^\p{RGI_Emoji}$/v.test('😵💫'), true
);
String literals via \q{}
in character classes:
> /^[\q{😵💫}]$/v.test('😵💫')
true
> /^[\q{abc|def}]$/v.test('abc')
true
Set operations for character classes:
> /^[\w--[a-g]]$/v.test('a')
false
> /^[\p{Number}--[0-9]]$/v.test('٣')
true
> /^[\p{RGI_Emoji}--\q{😵💫}]$/v.test('😵💫')
false
Improved matching with /i
if a Unicode property escape is negated via [^···]
ArrayBuffers get two new features:
const buf = new ArrayBuffer(2, {maxByteLength: 4});
// `typedArray` starts at offset 2
const typedArray = new Uint8Array(buf, 2);
assert.equal(
typedArray.length, 0
);
buf.resize(4);
assert.equal(
typedArray.length, 2
);
.transfer()
for transferring them.SharedArrayBuffers can be resized, but they can only grow and never shrink. They are not transferrable and therefore don’t get the method .transfer()
that ArrayBuffers
got.
Two new methods help us ensure that strings are well-formed (w.r.t. UTF-16 code units):
.isWellFormed()
checks if a JavaScript string is well-formed and does not contain any lone surrogates..toWellFormed()
returns a copy of the receiver where each lone surrogate is replaced with the code unit 0xFFFD (which represents the code point with the same number, whose name is “replacement character”). The result is therefore well-formed.Atomics.waitAsync()
Atomics.waitAsync()
lets us wait asynchronously for a change to shared memory. See the MDN Web Docs for more information.
My book “Exploring JavaScript (ES2024 Edition)” is free to read online. Two chapters are especially relevant: