ECMAScript 2025 (简称 ES16) 于 2025 年 6 月发布,带来了很多核心特性。
一、 异步与错误处理增强(Promise.try())
使用 Promise.try() 统一处理同步和异步操作的错误,避免 Promise.resolve().then() 的微任务延迟问题。
- 同步错误自动转为 Promise 拒绝,无需嵌套
try/catch - 调试更加直观,错误堆栈直接指向原始操作
Promise.try(() => {
if (Math.random() > 0.5) throw new Error('Sync error');
return 'Success';
})
.then(console.log)
// 同时捕获同步和异步的错误
.catch(console.error);
二、 数据结构扩展
1. Set 集合新方法
为 Set 新增 7 个方法:
- 运算符:
union()(并集)、intersection()(交集)、difference()(差集)、symmetricDifference()(对称差集) - 关系类:
isSubsetOf(子集判断)、isSupersetOf()(超集判断)、isDisjoinFrom()(无交集判断)
const setA = new Set([1, 2, 3]);
const setB = new Set([2, 3, 4]);
// Set {1, 2, 3, 4}
console.log(setA.union(setB));
2. 同步迭代辅助方法
新增链式操作: map()、filter()、take()(取前 n 项)、drop() (跳过前 n 项)、toArray()(转化为数组)等,支持惰性求值。
- 处理大型日志文件或流数据节省内容
- 对无序(如斐波那契数列)进行流式处理
function* fibonacci() {
let a = 0,
b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const result = fibonacci()
// 取前 20 项
.take(20)
// 过滤偶数
.filter(n => 0 === n % 2)
// 取平方
.map(n => n ** 2)
// 转化为数组
.toArray();
// [0, 4, 64, 1156, 20736, 372100, 6677056]
console.log(result);
三、 模块系统优化
1. JSON 模块导入
通过 with { type: 'json'} 直接导入 JSON 文件,无需手动解析。
- 消除了
fetch+JSON.parse的冗余代码,支持静态分析和打包优化 - 类型安全,导入的 JSON 自动解析为对象
import config from './config.json' with {type: 'json'};
console.log(config.name);
2. 延迟模块加载(defer import)
声明时预加载模块,但执行延迟到首次访问导出成员时。
defer import { heavyFunction } from './heavy-module.js';
// 首次调用时才会执行模块代码
button.addEventListener('click', () => heavyFunction());
- 优化首屏性能:大型应用中,非关键功能的模块(如 3D 渲染、复杂的表单验证)不再阻塞主线程,首屏加载速度可提升 30% 以上
- 替代动态
import():相比于import('./module.js'),defer import在声明时就开始预加载,避免了运行时等待网络请求,用户体验更佳
四、 正则表达式增强
1. RegExp.escape()
安全转义字符中的正则特殊字符(如: *、?、$) ,以防正则注入漏洞
/** 用户输入 */
const userInput = 'a*b';
/** 安全转义 */
const escaped = RegExp.escape(userInput);
const regex = new RegExp(escaped);
// true
console.log(regex.test('a*b'));
2. 正则內联标志
在子表达式中动态启动或禁止标志(如:i、m、s)。
/** 整个表达式忽略大小写,但 "def" 部分区分 */
const regex = /^(?i:abc)(?-i:def)$/;
console.log(regex.text('AbcDef')); // false
3. 重复命名捕获组
允许不同的分支复用同名捕获组,统一数据提取逻辑。
/ 匹配YYYY-MM-DD或MM/DD/YYYY格式日期
const dateRegex = /^(?<year>\d{4})-(?<month>\d{2})|(?<month>\d{2})|(?<day>\d{2})|(?<year>\d{4})$/;
console.log(dateRegex.exec('2025-06')?.groups.year); // '2025'
console.log(dateRegex.exec('06/25/2025')?.groups.year); // undefined
原文给出的示例代码、答案是错误的。在最新版本的 edge 浏览器第二个打印值为 undefined 而非 '2025'
五、 底层类型支持(新增 Float16Array)
使用 Float16Array 16 位浮点数在图形处理(WebGPU)、机器学习模型传输等场景储存大规模数值数据时节省 50% 内存。
const arr = new Float16Array([1.5, 2.5, 3.5]);
// 6 ( 3 元素 * 2 字节/元素)
console.log(arr.byteLength);
六、 显式资源管理
使用 using 声明的变量,通过 Symbol.dispose 在作用域结束时清理逻辑,自动释放文件句柄、网络连接等资源,避免内存泄漏。
class FileHandle {
[Symbol.dispose]() {
console.log('文件关闭');
}
}
{
// 块结束时自动调用 dispose
using file = new Filehandle();
}
// 输出:文件关闭
七、 模式匹配
- 支持对象、数组结构及条件分支,替代深层嵌套的
if-else - 可自定义匹配器(通过
Symbol.customMatcher)
const result = match(response) {
{status: 200 , data: [first, ...rest]} => `First: ${first}`,
{status: 404, } => 'Not Found',
{status: number} if (status >= 500) => 'Server error',
_ => 'Unknown'
}
不知所云
八、 智能管道符(|>)
将左侧表达式的结果作为右侧函数的输入,支持占位符 %。
const result = processData(transform(validate(input)));
使用管道符写法:
const result = input |> validate(%) |> transform(%) |> processData(%);
九、 原生类型注解(native type annotations)
在 JavaScript 中引入原生的类型声明语法,无需 TypeScript 编译器即可享受类型安全。
function sum(x: number, y: number): number {
return x + y;
}
const user: { name: string, age?: number } = { name: 'Tom' };
优势
降低使用静态类型的安全门槛,让 JavaScript 开发者在不引用 TypeScript 的情况下也能编写更健壮的代码。
- 零编译成本:直接在 V8 等引擎中运行,无需额外的编译步骤
- 运行时校验:在开发模式下启用运行时校验检查,提前发现类型错误
- 兼容 TypeScript: 100% 兼容现有的 TS 类型声明文件
十、 不可变数据结构
引入 Record (类似对象)和 Tuple (类似数组)两种新的深度不可变数据结构,通过 # 前缀声明(我个人觉得应当是标记,而不是像 using 那样的声明)。
const user = #{
name: 'Tom',
address: #[23.12, 113.25],
};
// 尝试修改会触发 TypeError
user.name = 'Jerry';
/** 值表会更快 */
const points = #[#[1, 2], #[3, 4]];
// true
points[0] === #[1, 2];