ECMAScript 2025(简称ES2025)是JavaScript的下一个主要版本,目前处于提案阶段(截至2024年)。以下是ES2025的已完成提案和关键特性,以及与过往版本的对比:
一、ES2025 新特性(已完成提案)
1. 类的装饰器(Class Decorators)
- 作用:在类、方法或属性上添加元数据或修改行为。
- 示例:
@log class User { @readonly name = 'Alice'; } function log(target) { console.log('Class decorated:', target.name); } function readonly(target, key, descriptor) { descriptor.writable = false; return descriptor; }
2. 模式匹配(Pattern Matching)
- 作用:类似
switch
的表达式语法,支持解构和复杂匹配。 - 示例:
const result = match(value) { case 1: return 'One'; case [a, b] if a > b: return 'Descending pair'; case { name: 'Alice' }: return 'Hi Alice'; default: return 'Unknown'; };
3. 异步生成器改进
- 作用:支持在
for await...of
循环中使用break
和continue
。 - 示例:
async function* generate() { yield 1; yield 2; await new Promise(resolve => setTimeout(resolve, 1000)); yield 3; } for await (const num of generate()) { if (num === 2) continue; // 跳过2 console.log(num); }
4. 符号属性的元数据(Symbol Metadata)
- 作用:为Symbol添加元数据,用于调试或反射。
- 示例:
const sym = Symbol('description', { type: 'id' }); console.log(Symbol.metadata(sym)); // { type: 'id' }
5. 数组分组(Array.prototype.groupBy)
- 作用:根据条件将数组元素分组为对象。
- 示例:
const people = [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }]; const grouped = people.groupBy(person => person.age > 28 ? 'adult' : 'young'); // { young: [{...}], adult: [{...}] }
二、ES2024 关键特性回顾
-
数组和字符串的复制方法
Array.prototype.toReversed()
、String.prototype.toUpperCase()
等不可变方法。
-
装饰器元数据(Metadata Reflection)
- 通过
Metadata
对象访问装饰器信息。
- 通过
-
管道操作符(|>)
- 函数调用的链式语法:
value |> fn1 |> fn2
。
- 函数调用的链式语法:
-
弱引用集合增强
WeakMap
和WeakSet
支持迭代器和has()
方法。
三、ES2023 关键特性回顾
-
Hashbang 语法
- 支持在脚本文件顶部添加
#!/usr/bin/env node
。
- 支持在脚本文件顶部添加
-
数组.findLast() 和 findLastIndex()
- 从数组末尾开始查找元素。
-
WeakMap 和 WeakSet 支持方法链
- 如
weakMap.set(key, value).get(key)
。
- 如
四、ES2022 关键特性回顾
-
类的静态块
class User { static { // 静态初始化代码 } }
-
Top-level await
- 模块顶层支持
await
。
- 模块顶层支持
-
Error Cause
- 错误链:
throw new Error('Failed', { cause: originalError })
。
- 错误链:
五、ES2021 关键特性回顾
-
逻辑赋值操作符
&&=
、||=
、??=
。
-
Promise.any() 和 AggregateError
- 首个Promise成功即返回,失败则抛出所有错误。
-
String.prototype.replaceAll()
- 直接替换所有匹配项。
六、ES2020 关键特性回顾(ES11)
-
BigInt
- 任意精度整数:
123456789012345678901234567890n
。
- 任意精度整数:
-
Promise.allSettled()
- 等待所有Promise完成(无论成功或失败)。
-
空值合并操作符(??)
value ?? defaultValue
。
七、ES2019 关键特性回顾(ES10)
-
Array.prototype.flat() 和 flatMap()
- 数组扁平化:
[1, [2, 3]].flat()
。
- 数组扁平化:
-
Object.fromEntries()
- 从键值对数组创建对象:
Object.fromEntries([['a', 1], ['b', 2]])
。
- 从键值对数组创建对象:
-
String.prototype.trimStart() 和 trimEnd()
- 去除字符串首尾空格。
八、ES2018 关键特性回顾(ES9)
-
异步迭代器(Async Iterators)
for await...of
循环。
-
Rest/Spread 属性
- 对象解构:
const { a, ...rest } = obj
。
- 对象解构:
-
Promise.finally()
- 无论Promise状态如何都会执行的回调。
九、ES2017 关键特性回顾(ES8)
-
async/await
- 异步编程语法糖:
async function fetchData() { const response = await fetch(url); return response.json(); }
- 异步编程语法糖:
-
Object.values() 和 Object.entries()
- 获取对象的值数组和键值对数组。
-
字符串填充(padStart/padEnd)
'42'.padStart(5, '0')
// ‘00042’。
十、ES2016 关键特性回顾(ES7)
-
指数操作符()**
2 ** 3
// 8。
-
Array.prototype.includes()
[1, 2, 3].includes(2)
// true。
十一、ES2015(ES6)—— 里程碑版本
- 箭头函数(() => {})
- 类(class)
- Promise
- 模块化(import/export)
- let/const
- 解构赋值
- 默认参数、扩展运算符(…)
- 模板字符串
- Map/Set/WeakMap/WeakSet
总结:版本演进趋势
版本 | 核心目标 | 代表特性 |
---|---|---|
ES2015 | 现代语法基础 | 箭头函数、Promise、class |
ES2016 | 小幅度增强 | 指数操作符、includes |
ES2017 | 异步编程优化 | async/await、Object.values |
ES2018 | 异步迭代与对象扩展 | 异步迭代器、Rest/Spread 属性 |
ES2019 | 数组与对象工具完善 | flat 、Object.fromEntries |
ES2020 | 新数据类型与错误处理 | BigInt、空值合并(??) |
ES2021 | 逻辑赋值与Promise改进 | &&= 、Promise.any |
ES2022 | 类与错误增强 | 静态块、Error Cause |
ES2023 | 数组与WeakMap改进 | findLast 、WeakMap方法链 |
ES2024 | 不可变操作与装饰器元数据 | toReversed 、装饰器反射 |
ES2025 | 模式匹配与类装饰器 | 模式匹配、类装饰器 |
从演进趋势可见,JavaScript正持续增强:
- 语法糖(如模式匹配、管道操作符);
- 异步编程(从Promise到async/await再到异步生成器);
- 元编程能力(装饰器、反射API);
- 不可变数据处理(数组复制方法)。
代码解释:
- 示例:
async function* generate() { yield 1; yield 2; await new Promise(resolve => setTimeout(resolve, 1000)); yield 3; } for await (const num of generate()) { if (num === 2) continue; // 跳过2 console.log(num); }
这段代码展示了JavaScript中**异步生成器(Async Generator)和异步迭代(Async Iteration)**的结合使用。以下是逐行解释:
1. 定义异步生成器函数
async function* generate() {
async function*
:声明一个异步生成器函数,它返回一个异步迭代器对象。- 异步生成器可使用
yield
暂停执行,并支持await
处理异步操作。
2-4. 生成值并暂停
yield 1;
yield 2;
await new Promise(resolve => setTimeout(resolve, 1000));
yield 1
:立即返回值1
,并暂停函数执行。yield 2
:恢复执行后,返回值2
,再次暂停。await ...
:等待1秒后再继续执行下一步。
5. 生成最终值
yield 3;
- 1秒后,返回值
3
。
7-10. 异步迭代生成器产出的值
for await (const num of generate()) {
if (num === 2) continue; // 跳过2
console.log(num);
}
for await...of
:专门用于异步迭代的循环,每次迭代等待异步操作完成。generate()
:调用异步生成器函数,返回异步迭代器。if (num === 2) continue
:当值为2
时,跳过当前循环,不打印。console.log(num)
:打印值1
和3
(值2
被跳过)。
执行流程时序图
0s: 调用generate() → 生成器启动并yield 1 → 循环打印1
0s: 生成器yield 2 → 循环遇到continue,跳过打印2
0s: 生成器await Promise(暂停1秒)
1s: Promise完成 → 生成器yield 3 → 循环打印3
关键点总结
- 异步生成器:通过
async function*
定义,可使用yield
和await
。 - 异步迭代:
for await...of
自动处理异步操作,按顺序等待每个值。 - 暂停与恢复:生成器在
yield
处暂停,在await
处等待异步操作完成。 - 控制流:
continue
可跳过特定值,不影响生成器的执行。
这种模式常用于流式处理异步数据,例如从网络分批获取数据并处理,同时避免阻塞主线程。