ES6(2015)至 ES12(2021)是 JavaScript 语言发展的关键阶段,每一代都新增了大量实用特性,从语法糖到核心能力扩展,极大提升了开发效率和语言表现力。以下按版本梳理核心特性,结合使用场景和示例,帮你全面理解:
一、ES6(2015)—— 里程碑式版本(奠定现代 JS 基础)
ES6 是改动最大、影响最深远的版本,引入了众多核心特性,彻底改变了 JS 编程方式。
核心特性
-
块级作用域与变量声明:
let(块级变量)、const(常量,不可重新赋值)- 解决
var变量提升、作用域污染问题。
if (true) { let x = 1; // 块级作用域,外部无法访问 const y = 2; // 常量,不可修改 } console.log(x); // ReferenceError: x is not defined - 解决
-
箭头函数(Arrow Function) :简洁语法 + 绑定外层
this- 无自己的
this,继承外层作用域的this;不能作为构造函数。
const add = (a, b) => a + b; // 简洁写法 const arr = [1, 2, 3]; arr.map(item => item * 2); // 遍历场景常用 - 无自己的
-
模板字符串(Template Literals) :支持多行字符串 + 变量插值
const name = '张三'; const str = `Hello ${name}! 这是多行字符串`; // 无需拼接,保留换行 -
解构赋值(Destructuring) :快速提取数组 / 对象的属性
// 数组解构 const [a, b, ...rest] = [1, 2, 3, 4]; // a=1, b=2, rest=[3,4] // 对象解构 const { name, age } = { name: '李四', age: 25 }; // 按属性名匹配 -
扩展运算符与剩余参数(...) :展开 / 收集元素
// 扩展运算符:展开数组/对象 const arr1 = [1, 2]; const arr2 = [...arr1, 3, 4]; // [1,2,3,4] // 剩余参数:收集函数参数 function sum(...args) { return args.reduce((a, b) => a + b); } sum(1,2,3); // 6 -
对象字面量增强:属性简写、方法简写、计算属性名
const name = '张三'; const obj = { name, // 属性简写(等价于 name: name) sayHi() {}, // 方法简写(等价于 sayHi: function() {}) [name + 'age']: 25 // 计算属性名 }; -
Promise:异步编程标准方案,解决回调地狱
- 三种状态:
pending(等待)、fulfilled(成功)、rejected(失败)
const promise = new Promise((resolve, reject) => { setTimeout(() => resolve('成功'), 1000); }); promise.then(res => console.log(res)).catch(err => console.log(err)); - 三种状态:
-
类(Class) :语法糖,简化原型链编程
- 支持
constructor、extends(继承)、super(调用父类)
class Person { constructor(name) { this.name = name; } sayHi() { console.log(`Hi ${this.name}`); } } class Student extends Person { constructor(name, age) { super(name); this.age = age; } } - 支持
-
模块系统(Module) :
import/export导入导出- 取代 CommonJS(
require/module.exports),成为浏览器和 Node.js 通用模块方案。
// 导出 export const add = (a, b) => a + b; export default class Person {} // 导入 import { add } from './utils.js'; import Person from './Person.js'; - 取代 CommonJS(
-
其他重要特性:
Symbol:第七种基本类型,唯一不可变,用于对象唯一属性名。Iterator:迭代器协议,支持for...of遍历(数组、Set、Map 等原生支持)。Generator:生成器函数(function*),支持暂停 / 恢复执行,用于异步迭代。
二、ES7(2016)—— 小版本迭代(补充实用特性)
ES7 仅新增 2 个核心特性,聚焦 “常用功能补全”。
核心特性
-
Array.prototype.includes() :判断数组是否包含指定元素(比
indexOf更直观,支持NaN)[1, 2, 3].includes(2); // true [1, NaN, 3].includes(NaN); // true(indexOf 无法识别 NaN) -
指数运算符( )**:简洁表示幂运算(替代
Math.pow())2 ** 3; // 8(等价于 Math.pow(2, 3)) 4 ** 0.5; // 2(开平方)
三、ES8(2017)—— 异步与对象增强
核心聚焦异步编程优化和对象工具方法。
核心特性
-
Async/Await:异步编程语法糖,基于 Promise,让异步代码像同步一样直观
async函数返回 Promise,await可暂停执行直到 Promise 完成。
async function fetchData() { try { const res = await fetch('https://api.example.com'); // 暂停等待结果 const data = await res.json(); return data; } catch (err) { console.log(err); } } -
Object.values()/Object.entries() :快速获取对象的 “值数组”/“键值对数组”
const obj = { name: '张三', age: 25 }; Object.values(obj); // ['张三', 25] Object.entries(obj); // [['name', '张三'], ['age', 25]](可迭代,支持 for...of) -
Object.getOwnPropertyDescriptors() :获取对象所有属性的描述符(用于深拷贝、继承)
const obj = { a: 1 }; Object.getOwnPropertyDescriptors(obj); // { a: { value: 1, writable: true, enumerable: true, configurable: true } } -
字符串填充(padStart ()/padEnd ()) :在字符串开头 / 结尾填充指定字符,补全长度
'5'.padStart(2, '0'); // '05'(补全为 2 位,不足用 0 填充) 'abc'.padEnd(5, '-'); // 'abc--'(补全为 5 位,不足用 - 填充)
四、ES9(2018)—— 正则与异步迭代
核心优化正则表达式能力,支持异步迭代。
核心特性
-
异步迭代器(Async Iterator) :支持
for await...of遍历异步可迭代对象- 解决异步场景下的遍历问题(如遍历异步接口返回的多个结果)。
// 异步生成器(返回异步可迭代对象) async function* asyncGenerator() { yield Promise.resolve(1); yield Promise.resolve(2); } // 异步遍历 (async () => { for await (const num of asyncGenerator()) { console.log(num); // 1 → 2(等待每个 Promise 完成) } })(); -
正则表达式增强:
-
命名捕获组:给正则捕获组命名,便于读取结果。
const reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; const match = reg.exec('2025-11-07'); match.groups.year; // '2025'(通过名称获取捕获结果) -
反向断言(Lookbehind):匹配 “前面 / 后面” 满足条件的字符(正反向先行 / 后行断言)。
// 正后行断言:匹配 $ 前面的数字 const reg = /(?<=$)\d+/; '$100'.match(reg); // ['100'] -
Unicode 属性转义(
\p{Property}):匹配 Unicode 字符属性(如中文、字母)。/\p{Script=Han}/u.test('中文'); // true(匹配中文) /\p{Letter}/u.test('a'); // true(匹配字母)
-
-
对象展开运算符(Object Spread) :正式标准化对象展开(ES6 仅支持数组,ES9 扩展到对象)
const obj1 = { a: 1 }; const obj2 = { ...obj1, b: 2 }; // { a: 1, b: 2 }(浅拷贝 + 合并)
五、ES10(2019)—— 数组与字符串优化
聚焦数组、字符串的实用工具方法,修复部分痛点。
核心特性
-
Array.prototype.flat()/flatMap() :数组扁平化
flat(depth):将多维数组转为一维 / 指定深度数组(默认深度 1)。flatMap():先执行map,再执行flat(1)(性能更优)。
[1, [2, [3]]].flat(); // [1, 2, [3]](深度 1) [1, [2, [3]]].flat(2); // [1, 2, 3](深度 2) [1, 2, 3].flatMap(x => [x * 2]); // [2, 4, 6](等价于 map + flat(1)) -
String.prototype.trimStart()/trimEnd() :精准去除字符串首尾空白(替代
trimLeft/trimRight)' abc '.trimStart(); // 'abc '(仅去开头空白) ' abc '.trimEnd(); // ' abc'(仅去结尾空白) -
Object.fromEntries() :将 “键值对数组” 转为对象(
Object.entries()的逆操作)const entries = [['name', '张三'], ['age', 25]]; Object.fromEntries(entries); // { name: '张三', age: 25 } -
可选捕获组(Optional Catch Binding) :
catch块可省略参数(无需使用时)try { // 可能出错的代码 } catch { // 无需写 catch(err) console.log('出错了'); } -
BigInt:支持任意精度整数(解决
Number最大安全整数2^53-1限制)const bigNum = 9007199254740991n; // 后缀 n 表示 BigInt bigNum + 2n; // 9007199254740993n(无精度丢失)
六、ES11(2020)—— 实用特性爆发
新增多个高频使用特性,覆盖空值处理、动态导入、字符串等场景。
核心特性
-
可选链运算符(Optional Chaining) :
?.简化嵌套对象属性访问(避免Cannot read property 'x' of undefined错误)const user = { name: '张三', address: { city: '北京' } }; user.address?.city; // '北京'(存在则访问) user.address?.street?.name; // undefined(中间属性不存在,返回 undefined) -
空值合并运算符(Nullish Coalescing) :
??解决||的 “假值覆盖” 问题(仅当左侧为null/undefined时才取右侧)0 || '默认值'; // '默认值'(0 是假值,被错误覆盖) 0 ?? '默认值'; // 0(仅 null/undefined 才取右侧) null ?? '默认值'; // '默认值' -
动态导入(Dynamic Import) :
import()函数按需导入模块(返回 Promise,支持代码分割)- 用于路由懒加载、按需加载大模块,优化性能。
// 按需导入 utils.js document.getElementById('btn').addEventListener('click', async () => { const { add } = await import('./utils.js'); console.log(add(1, 2)); // 3 }); -
字符串匹配所有(String.prototype.matchAll ()) :返回正则匹配的所有结果(包括捕获组)
const str = 'a1b2c3'; const reg = /(\w)(\d)/g; [...str.matchAll(reg)]; // 每个元素是匹配结果数组,包含捕获组: // [['a1', 'a', '1'], ['b2', 'b', '2'], ['c3', 'c', '3']] -
Promise.allSettled() :等待所有 Promise 完成(无论成功 / 失败),返回所有结果状态
- 区别于
Promise.all()(一败俱败),适合需要知道所有异步操作结果的场景。
const promises = [Promise.resolve(1), Promise.reject('错误')]; Promise.allSettled(promises).then(res => { console.log(res); // [ // { status: 'fulfilled', value: 1 }, // { status: 'rejected', reason: '错误' } // ] }); - 区别于
-
全球对象(globalThis) :统一所有环境的全局对象(浏览器
window、Node.jsglobal、Workerself)globalThis.console.log('Hello'); // 所有环境通用
七、ES12(2021)—— 语法糖与性能优化
新增实用语法糖和性能相关特性,提升开发效率。
核心特性
-
逻辑赋值运算符(Logical Assignment Operators) :逻辑运算符与赋值结合(
||=,&&=,??=)let a = 1; a ||= 2; // 等价于 a = a || 2 → 1(a 为真,不变) a &&= 2; // 等价于 a = a && 2 → 2(a 为真,赋值 2) let b = null; b ??= 3; // 等价于 b = b ?? 3 → 3(b 为 null,赋值 3) -
数字分隔符(Numeric Separators) :
_分隔数字,提升可读性(不影响数值)const num = 1_000_000_000; // 10亿,可读性更强 1_234.56_78; // 小数也支持 -
Promise.any() :等待第一个成功的 Promise,所有失败则返回
AggregateError- 区别于
Promise.race()(第一个完成,无论成功失败),聚焦 “成功结果”。
const promises = [Promise.reject('错1'), Promise.resolve(2), Promise.reject('错2')]; Promise.any(promises).then(res => console.log(res)); // 2(第一个成功的结果) - 区别于
-
WeakRef 与 FinalizationRegistry:弱引用相关 API(进阶特性)
WeakRef:创建对象的弱引用(不影响垃圾回收)。FinalizationRegistry:对象被垃圾回收时触发回调(用于资源清理)。
const registry = new FinalizationRegistry(value => { console.log(`清理资源:${value}`); }); let obj = {}; registry.register(obj, 'obj 的资源'); // 注册对象与关联值 obj = null; // 释放强引用,后续垃圾回收时触发回调
八、版本特性总结与使用建议
| 版本 | 核心亮点 | 高频使用特性 |
|---|---|---|
| ES6 | 现代 JS 基础 | let/const、箭头函数、Promise、解构、模块 |
| ES7 | 实用小特性 | includes ()、指数运算符 |
| ES8 | 异步与对象增强 | Async/Await、Object.values/entries |
| ES9 | 正则与异步迭代 | 命名捕获组、for await...of |
| ES10 | 数组与字符串优化 | flat/flatMap、Object.fromEntries |
| ES11 | 空值处理与按需加载 | 可选链、空值合并、动态导入 |
| ES12 | 语法糖与可读性 | 逻辑赋值、数字分隔符、Promise.any |
使用建议
- 优先掌握 ES6-ES11 核心特性:这些是日常开发的 “必备技能”(如解构、Async/Await、可选链)。
- 结合编译工具使用:通过 Babel 编译低版本不支持的特性,确保兼容性(如 ES6 的
class、ES11 的可选链)。 - 按需使用进阶特性:如
WeakRef、正则 Unicode 转义等,根据场景选择,无需盲目全用。
这些版本的演进趋势是:简化语法、优化异步编程、增强原生 API、提升可读性和开发效率,让 JavaScript 更适合大型应用开发。