ES2024 新特性详解
2024 年 6 月 26 日,Ecma 国际正式批准了 ECMAScript 2024(第 15 版)语言规范。ES2024 带来了分组迭代、Promise 创建新方式、正则表达式增强、ArrayBuffer 可调整大小等实用特性,进一步丰富了 JavaScript 的能力。下面让我们深入了解这些新特性。
Map.groupBy() 和 Object.groupBy()
ES2024 为同步可迭代对象提供了分组能力。Map.groupBy() 根据回调函数返回的键将迭代项分组到 Map 中,Object.groupBy() 则返回普通对象。
const numbers = [0, -5, 3, -4, 8, 9];
// 按正负零分组
Map.groupBy(numbers, (x) => Math.sign(x));
// Map(3) { 0 => [0], -1 => [-5, -4], 1 => [3, 8, 9] }
Object.groupBy(numbers, (x) => Math.sign(x));
// { '0': [0], '-1': [-5, -4], '1': [3, 8, 9] }
Map.groupBy() 的键可以是任意类型(包括对象),而 Object.groupBy() 的键会被转换为字符串。选择哪个方法取决于你的使用场景。
Promise.withResolvers()
传统创建 Promise 时,resolve 和 reject 被包裹在构造函数内部,有时需要在外部控制 Promise 的完成状态。Promise.withResolvers() 提供了一种更直接的方式:
const { promise, resolve, reject } = Promise.withResolvers();
// 在异步操作完成后调用
fetch('/api/data')
.then((res) => res.json())
.then(resolve)
.catch(reject);
// 其他地方可以 await 这个 promise
const data = await promise;
这在需要将 resolve/reject 传递给外部回调或事件监听器时非常有用。
正则表达式 /v 标志(Unicode 集合)
ES2024 新增正则表达式 /v 标志(unicodeSets),带来了多项增强:
Unicode 字符串属性
使用 RGI_Emoji 等属性可以正确匹配包含多个码点的 emoji:
// 之前:/u 标志下无法正确匹配多码点 emoji
/^\p{Emoji}$/u.test('😵💫'); // false
// 新:/v 标志支持 RGI_Emoji
/^\p{RGI_Emoji}$/v.test('😵💫'); // true
字符类中的 \q{} 字符串字面量
在字符类中可以直接匹配特定字符串:
/^[\q{😵💫}]$/v.test('😵💫'); // true
/^[\q{abc|def}]$/v.test('abc'); // true
字符类集合运算
支持交集(--)、差集等集合运算:
// 匹配 \w 但不包含 a-g
/^[\w--[a-g]]$/v.test('a'); // false
/^[\w--[a-g]]$/v.test('h'); // true
// 匹配数字但不包含 ASCII 数字
/^[\p{Number}--[0-9]]$/v.test('٣'); // true
ArrayBuffer 和 SharedArrayBuffer 增强
ArrayBuffer 可调整大小
创建 ArrayBuffer 时可指定 maxByteLength,之后可以调用 resize() 调整大小:
const buf = new ArrayBuffer(2, { maxByteLength: 4 });
const typedArray = new Uint8Array(buf, 2);
typedArray.length; // 0
buf.resize(4);
typedArray.length; // 2
ArrayBuffer.transfer()
transfer() 方法可以转移 ArrayBuffer 的所有权,原 buffer 会被分离(detached):
const oldBuffer = new ArrayBuffer(8);
const newBuffer = oldBuffer.transfer(16); // 可指定新大小
// oldBuffer 已分离,无法再使用
SharedArrayBuffer 也可以调整大小,但只能增大不能缩小,且不支持 transfer()。
字符串 Well-Formed 方法
ES2024 新增两个方法用于处理 UTF-16 编码的字符串完整性:
String.prototype.isWellFormed()
检查字符串是否格式良好,即是否包含孤立的代理项(lone surrogate):
const str = 'Hello\uD800World'; // \uD800 是孤立的代理项
str.isWellFormed(); // false
'Hello'.isWellFormed(); // true
String.prototype.toWellFormed()
返回格式良好的副本,将孤立代理项替换为替换字符 U+FFFD:
const str = 'Hello\uD800World';
str.toWellFormed(); // 'Hello\uFFFDWorld'
Atomics.waitAsync()
Atomics.waitAsync() 允许异步等待共享内存的变化,适用于 Web Worker 等场景中的异步通信,无需阻塞主线程。
ES2024 的这些新特性在数据分组、异步编程、正则匹配、内存管理以及字符串处理等方面都带来了显著改进。随着主流浏览器和 Node.js 的逐步支持,开发者可以充分利用这些特性来构建更高效、更健壮的应用。
