目录:
✅ ES7 / ES2016 数组includes方法、指数运算符
✅ ES8 / ES2017 async/await异步方案、Object.values/entries
✅ ES10 / ES2019 数组flat/flatMap、Object.fromEntries
✅ ES11 / ES2020 可选链?.、空值合并??、Promise.allSettled
✅ ES12 / ES2021 replaceAll、Promise.any、逻辑赋值运算符
✅ ES14 / ES2023 数组非破坏性方法(toSorted等)
✅ ES6 / ES2015(最关键的一次更新)
这是 ES5 之后最重要的升级
let/const(块级作用域变量声明)- 箭头函数
()=>{}(简写 + 自动绑定 this) - 模板字符串
`Hello, ${name}` - 解构赋值
const {a, b} = obj、数组解构[x, y] = arr - 默认参数
function f(x = 1) {} - 扩展运算符
...(对象 / 数组展开与收集) - for...of(用于遍历可迭代对象)
Map和Set数据结构- class 类的语法
- Promise(异步处理)【Promise 技术快速入门】
import / export(模块化)
✅ ES7 / ES2016 数组includes方法、指数运算符
Array.prototype.includes():判断数组中是否存在某个值- 指数运算符
**(例:2 ** 3 === 8)Math.pow(a, b)的简写语法
console.log(2 ** 3); // 8 → 2 * 2 * 2
console.log(5 ** 2); // 25 → 5 * 5
console.log(9 ** 0.5); // 3 → √9
✅ ES8 / ES2017 async/await异步方案、Object.values/entries
async / await(基于 Promise 的异步语法糖)Object.values()/Object.entries()
const user = { name: "Alice", age: 25, gender: "female" };
console.log(Object.values(user));
// 👉 ["Alice", 25, "female"]
console.log(Object.entries(user));
// 👉 [["name", "Alice"], ["age", 25], ["gender", "female"]]
String.prototype.padStart()/padEnd()字符串“填充”对齐
"5".padStart(3, "0") // "005"
"5".padEnd(3, "0") // "500"
"abc".padStart(6, "-") // "---abc"
"abc".padEnd(6, "-") // "abc---"
✅ ES9 / ES2018 异步迭代器、正则增强
...rest运算符支持对象剩余参数- 异步迭代器
for await...of
for await (const item of asyncIterable) {
// 每次 item 是 await 出来的值
}
// 异步生成器
async function* asyncGenerator() {
const values = [1, 2, 3];
for (const v of values) {
await new Promise(resolve => setTimeout(resolve, 1000));
yield v;
}
}
(async () => {
for await (const num of asyncGenerator()) {
console.log("Received:", num);
}
})();
// Received: 1
// Received: 2
// Received: 3
// 按块异步读取大文件(node)
const fs = require('fs');
async function readFileByLine(path) {
const rl = require('readline').createInterface({
input: fs.createReadStream(path),
crlfDelay: Infinity
});
for await (const line of rl) {
console.log('Line:', line);
}
}
// 命名识别 增强写法
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = re.exec("2025-07-31");
console.log(match.groups.year); // "2025"
console.log(match.groups.month); // "07"
// ----传统
const result = /(\d{4})-(\d{2})-(\d{2})/.exec("2025-07-31");
console.log(result[1]); // "2025" 年
✅ ES10 / ES2019 数组flat/flatMap、Object.fromEntries
Array.prototype.flat()/flatMap() 扁平数据,多维数据展开为一维数组Object.fromEntries()(配合Object.entries()用)
// 场景一
Object.fromEntries([["a", 1], ["b", 2]])
// => { a: 1, b: 2 }
// 场景二
const user = {
id: 123,
name: "Alice",
password: "secret"
};
// 去掉 password 字段
const safeUser = Object.fromEntries(
Object.entries(user).filter(([key]) => key !== "password")
);
// { id: 123, name: "Alice" }
trimStart()/trimEnd()清除字符串开头或结尾的空白字符
✅ ES11 / ES2020 可选链?.、空值合并??、Promise.allSettled
- 可选链操作符
?. - 空值合并运算符
?? let result = a ?? b如果a是null或undefined,返回b;否则返回 a; Promise.allSettled()专门用于“我不管成功失败,全部跑完后告诉我每个的状态”的场景。
const p1 = Promise.resolve("✅ 成功");
const p2 = Promise.reject("❌ 失败");
const p3 = Promise.resolve("✅ 又成功");
Promise.allSettled([p1, p2, p3]).then(results => {
console.log(results);
});
// 输出
[
{ status: "fulfilled", value: "✅ 成功" },
{ status: "rejected", reason: "❌ 失败" },
{ status: "fulfilled", value: "✅ 又成功" }
]
- 动态 import()(异步加载模块) 允许按需异步加载模块,非常适合大型应用、懒加载、条件加载等场景。
✅ ES12 / ES2021 replaceAll、Promise.any、逻辑赋值运算符
- String.prototype.replaceAll() 用来一次性替换所有匹配的子串
Promise.any()是对Promise.all()和Promise.race()的一种补充,非常适合“只要有一个成功就行”的场景。Promise.all race any三个对比
// ----- 多个请求,哪个先成功就用哪个
const p1 = Promise.reject("❌");
const p2 = new Promise(resolve => setTimeout(() => resolve("✅ p2"), 100));
const p3 = new Promise(resolve => setTimeout(() => resolve("✅ p3"), 200));
Promise.any([p1, p2, p3]).then(result => {
console.log(result); // ✅ "p2"
});
// ------ 失败情况(都失败才失败)
const p1 = Promise.reject("fail 1");
const p2 = Promise.reject("fail 2");
Promise.any([p1, p2]).catch(error => {
console.log(error instanceof AggregateError); // true
console.log(error.errors); // ["fail 1", "fail 2"]
});
- WeakRef / FinalizationRegistry(高级内存管理) 主要用于高性能缓存、资源清理、避免内存泄漏等 简单了解入门
- 逻辑赋值运算符:
&&=,||=,??=
| 运算符 | 等价于 | 说明 |
|---|---|---|
&&= | a = a && b | 如果 a 是真值,才赋值 b |
| ` | =` | |
??= | a = a ?? b | 如果 a 是 null 或 undefined,才赋值 b |
🔹 1. &&= 示例(“如果已有,就更新”)
let name = "Alice";
name &&= "Bob"; // name 是真值 → 更新为 "Bob"
console.log(name); // Bob
let username = "";
username &&= "Default"; // username 是假值 → 不变
console.log(username); // ""
🔹 2. ||= 示例(“如果没有,就补上默认值”)
let count = 0;
count ||= 10; // count 是假值 → 更新为 10
console.log(count); // 10
let level = 5;
level ||= 1; // level 是真值 → 保持不变
console.log(level); // 5
🔹 3. ??= 示例(“空才赋值,不影响 0 / false”)
let title = null;
title ??= "Untitled"; // 是 null → 更新
console.log(title); // "Untitled"
let value = 0;
value ??= 42; // 不是 null/undefined → 不变
console.log(value); // 0
| 场景 | 推荐使用 |
|---|---|
有值才覆盖(类似 if (a)) | &&= |
| 没值就填默认值(如“空字符串”) | ` |
| 只考虑 null / undefined | ??= |
✅ ES13 / ES2022 顶层await、类字段声明
- 顶层 await(模块顶层直接用
await) 简化模块初始化时异步操作
// -------以前
// ❌ 顶层不能直接 await(ES2021 之前)
const data = await fetchData(); // 报错!
// ✅ 只能这么写
(async () => {
const data = await fetchData();
})();
// ----- 现在 ✅ 注意:只能在 ES 模块(ESM)中用!
// ✅ 只要这个 JS 文件是模块(type="module" 或 .mjs)
const res = await fetch('https://api.example.com/data');
const data = await res.json();
console.log(data);
| 要点 | 说明 |
|---|---|
| 哪些地方能用? | 模块最外层(ES module 中) |
| 用来干啥? | 模块初始化时先 await 异步数据、动态导入库等 |
| 有什么好处? | 写法更自然,不需要包一层 IIFE 或异步函数 |
- 类字段声明语法(public 和 private) 目的是让你在
class里直接声明属性,不用都写在构造函数里
✅ ES14 / ES2023 数组非破坏性方法(toSorted等)
Array.prototype.toSorted(),toReversed(),with()( 都是 不修改原数组,而是返回新数组的“非破坏性”方法,非常适合函数式编程并避免副作用 )
| 方法 | 作用 | 是否修改原数组 |
|---|---|---|
toSorted() | 返回排序后的新数组 | 否 |
toReversed() | 返回反转后的新数组 | 否 |
with() | 返回修改指定元素的新数组 | 否 |
Symbol.prototype.description方便读取 Symbol 的描述字符串,而不用再通过toString()截取
✅ ES15 / ES2024(正在推进, 还没完全定稿 )
- 主要是一些补充,比如
Set.prototype.intersection()、union()等集合操作方法。
原文地址-原创