JavaScript 从 ES2015 到 ES2026 的核心更新梳理
ES2015 (ES6) - 里程碑式更新
这是 JS 史上最重大的一次更新,重构了语言核心语法和特性:
-
块级作用域与声明
-
let/const:替代var,提供块级作用域,const声明只读常量 -
示例:
-
const PI = 3.14159; let count = 0; if (true) { let count = 1; // 块内独立作用域 console.log(count); // 1 } console.log(count); // 0
-
-
-
箭头函数:简化函数写法,绑定词法
this-
const add = (a, b) => a + b; const obj = { name: "JS", sayHi: () => console.log(this.name) // 箭头函数this指向外层(全局) };
-
-
类与模块
class语法:简化原型链编程import/export:模块化标准-
// 模块导出 export const name = "ES6"; export class Person { constructor(name) { this.name = name; } } // 模块导入 import { Person } from './module.js';
-
解构赋值:快速提取对象/数组数据
-
const [a, b] = [1, 2]; const { name, age } = { name: "Tom", age: 20 };
-
-
其他核心特性:模板字符串
`hello ${name}`、默认参数、扩展运算符...、Promise、Map/Set等。
ES2016 (ES7) - 小版本增量更新
-
数组
includes()方法:替代indexOf判断元素是否存在(支持NaN)-
[1, 2, NaN].includes(NaN); // true [1, 2, NaN].indexOf(NaN); // -1
-
-
幂运算符
**:替代Math.pow()-
2 ** 3; // 8 等同于 Math.pow(2, 3)
-
ES2017 (ES8)
-
async/await:异步编程终极方案,简化 Promise 链式调用-
async function fetchData() { try { const res = await fetch('/api/data'); const data = await res.json(); return data; } catch (err) { console.error(err); } }
-
-
对象扩展
Object.values()/Object.entries():获取对象值/键值对数组Object.getOwnPropertyDescriptors():获取对象属性完整描述-
const obj = { a: 1, b: 2 }; Object.values(obj); // [1, 2] Object.entries(obj); // [['a', 1], ['b', 2]]
-
字符串填充:
padStart()/padEnd()-
'123'.padStart(5, '0'); // '00123' '123'.padEnd(5, '0'); // '12300'
-
ES2018 (ES9)
-
异步迭代器:
for await...of遍历异步可迭代对象-
async function processAsyncData() { const asyncIterable = { [Symbol.asyncIterator]() { let i = 0; return { next() { if (i < 3) return Promise.resolve({ value: i++, done: false }); return Promise.resolve({ done: true }); } }; } }; for await (const num of asyncIterable) { console.log(num); // 0, 1, 2 } }
-
-
正则扩展:反向断言、
dotAll模式(.匹配任意字符)-
// 后行断言 /(?<=$)\d+/.exec('$100'); // ['100'] // dotAll 模式 /a.b/s.test('a\nb'); // true(默认模式下为 false)
-
-
对象扩展运算符:
...解构/合并对象-
const obj1 = { a: 1 }; const obj2 = { ...obj1, b: 2 }; // { a: 1, b: 2 }
-
ES2019 (ES10)
-
数组方法扩展
Array.prototype.flat():扁平化数组(默认1层)Array.prototype.flatMap():map + flat组合-
[1, [2, [3]]].flat(2); // [1, 2, 3] [1, 2, 3].flatMap(x => [x * 2]); // [2, 4, 6]
-
字符串
trimStart()/trimEnd():替代trimLeft()/trimRight(),语义更清晰 -
Object.fromEntries():将键值对数组转回对象(Object.entries反向操作)-
const arr = [['a', 1], ['b', 2]]; Object.fromEntries(arr); // { a: 1, b: 2 }
-
-
可选捕获绑定:
try/catch中catch可以省略参数-
try { // 可能出错的代码 } catch { // 无需写 (err) // 处理错误(无需使用err参数时) }
-
ES2020 (ES11)
-
可选链操作符
?.:避免访问嵌套对象属性时的Cannot read property 'xxx' of undefined错误-
const obj = { a: { b: 1 } }; console.log(obj?.a?.b); // 1 console.log(obj?.c?.d); // undefined(不会报错)
-
-
空值合并运算符
??:仅当左侧为null/undefined时返回右侧(区别于||)-
0 ?? 1; // 0(|| 会返回1) null ?? 1; // 1
-
-
BigInt:支持超大整数运算(超出Number.MAX_SAFE_INTEGER范围)-
const bigNum = 9007199254740991n + 2n; // 9007199254740993n
-
-
import()动态导入:按需加载模块(返回 Promise)-
async function loadModule() { const module = await import('./module.js'); module.doSomething(); }
-
ES2021 (ES12)
-
数字分隔符
_:提升大数字可读性-
const billion = 1_000_000_000; // 等同于 1000000000
-
-
String.prototype.replaceAll():替换所有匹配项(无需正则全局标志)-
'a b a b'.replaceAll('a', 'x'); // 'x b x b'
-
-
Promise.any():只要有一个 Promise 成功就返回(区别于Promise.race)-
Promise.any([Promise.reject(1), Promise.resolve(2)]) .then(res => console.log(res)); // 2
-
-
逻辑赋值运算符:
&&=、||=、??=-
let a = 0; a ||= 1; // 1(等同于 a = a || 1) let b = 2; b &&= 3; // 3(等同于 b = b && 3) let c = null; c ??= 4; // 4(等同于 c = c ?? 4)
-
ES2022 (ES13)
-
类字段声明:支持在类中直接声明实例/静态字段(无需在 constructor 中赋值)
-
class Person { name = 'Tom'; // 实例字段 static age = 20; // 静态字段 #privateField = '私有值'; // 私有字段(# 开头) getPrivate() { return this.#privateField; } } const p = new Person(); console.log(p.name); // Tom console.log(Person.age); // 20 console.log(p.#privateField); // 报错(无法访问私有字段)
-
-
at()方法:支持数组/字符串负索引访问-
const arr = [1, 2, 3]; arr.at(-1); // 3(最后一个元素) 'hello'.at(-2); // 'l'
-
-
Object.hasOwn():替代Object.prototype.hasOwnProperty.call(),更安全-
const obj = { a: 1 }; Object.hasOwn(obj, 'a'); // true
-
-
Top-level
await:模块顶层可直接使用 await(无需包裹 async 函数)-
// module.js const data = await fetch('/api/data').then(res => res.json()); export default data;
-
ES2023 (ES14)
-
数组方法扩展:
findLast()/findLastIndex()(从后往前查找)-
const arr = [1, 2, 3, 2]; arr.findLast(x => x === 2); // 2(最后一个2) arr.findLastIndex(x => x === 2); // 3
-
-
Array.fromAsync():从异步可迭代对象创建数组-
async function test() { const asyncIterable = (async function* () { yield 1; yield 2; })(); const arr = await Array.fromAsync(asyncIterable); console.log(arr); // [1, 2] }
-
-
WeakMap 支持 Symbol 键:此前仅支持对象键
ES2024 (ES15)
-
Promise.withResolvers():简化 Promise 手动创建(替代手动声明 resolve/reject)-
// 旧写法 const promise1 = new Promise((resolve, reject) => { // 逻辑 }); // 新写法 const { promise: promise2, resolve, reject } = Promise.withResolvers();
-
-
正则
/v标志(Unicode 属性转义扩展) :更精准匹配 Unicode 字符-
// 匹配所有中文(更精准) /\p{Script=Han}/v.test('中文'); // true
-
-
Array.prototype.toReversed()/toSorted()/toSpliced():非破坏性数组方法(原数组不变)-
const arr = [3, 1, 2]; const sortedArr = arr.toSorted(); // [1, 2, 3] console.log(arr); // [3, 1, 2](原数组未变)
-
ES2025 (ES16) - 已定稿特性
-
Object.groupBy():按条件分组对象/数组(替代手动遍历分组)-
const arr = [1, 2, 3, 4, 5]; const grouped = Object.groupBy(arr, num => num % 2 === 0 ? 'even' : 'odd'); // { odd: [1, 3, 5], even: [2, 4] }
-
-
String.prototype.isWellFormed()/toWellFormed():处理无效 Unicode 字符-
const str = '\ud800'; // 无效 Unicode str.isWellFormed(); // false str.toWellFormed(); // '\ufffd'(替换为替换字符)
-
ES2026 (ES17) - 候选/提案阶段核心特性
(注:ES2026 尚未最终定稿,以下是当前进入 Stage 3+ 的核心提案)
-
管道运算符
|>:简化函数调用链(替代嵌套调用)-
// 旧写法 const result = multiply(add(1, 2), 3); // 9 // 新写法 const result = 1 |> add(2) |> multiply(3); // 9
-
-
Record/Tuple:不可变数据类型(Record 是不可变对象,Tuple 是不可变数组)-
const record = #{ name: 'Tom', age: 20 }; // 不可变Record const tuple = #[1, 2, 3]; // 不可变Tuple tuple.push(4); // 报错(不可变)
-
-
do表达式:将语句块转为表达式(可在赋值/返回中使用)-
const value = do { if (num > 10) 'big'; else 'small'; };
-
总结
- 核心演进逻辑:ES2015 奠定现代 JS 基础,后续版本以“增量更新”为主,聚焦简化开发(如
async/await、可选链)、增强安全性(如私有字段、Object.hasOwn)、提升可读性(如数字分隔符、管道运算符)、完善异步编程(如异步迭代、Promise.any)。 - 高频实用特性:日常开发中最常用的特性集中在 ES2015(
let/const、箭头函数、解构)、ES2017(async/await)、ES2020(可选链、空值合并)、ES2022(类字段、at())。 - 未来趋势:ES2026 重点探索不可变数据(
Record/Tuple)和语法简化(管道运算符),进一步提升代码的可维护性和性能。