JavaScript ES6 → ES2025
ES2015 (ES6) — 现代 JS 的起点
1. let / const
let x = 1; // 块级作用域,可重赋值
const y = 2; // 块级作用域,不可重赋值(引用不可变,内容可变)
不再使用
var(存在变量提升和函数作用域问题)
2. 箭头函数
const add = (a, b) => a + b;
const double = (n) => n * 2;
const getObj = () => ({ key: "value" }); // 返回对象加括号
// 不绑定自己的 this,继承外层上下文
class Timer {
start() {
setInterval(() => {
this.tick(); // this 指向 Timer 实例
}, 1000);
}
}
3. 模板字符串
const name = "Alice";
console.log(`Hello, ${name}!`);
console.log(`1 + 1 = ${1 + 1}`);
// 多行字符串
const html = `
<div>
<p>${name}</p>
</div>
`;
// 标签模板
function highlight(strings, ...values) {
return strings.reduce(
(result, str, i) =>
`${result}${str}${values[i] ? `<b>${values[i]}</b>` : ""}`,
"",
);
}
const msg = highlight`Hello ${name}, you are ${"awesome"}!`;
4. 解构赋值
// 数组解构
const [a, b, ...rest] = [1, 2, 3, 4, 5];
const [, second] = [1, 2]; // 跳过元素
const [x = 10] = []; // 默认值
// 对象解构
const { name, age = 18 } = user; // 默认值
const { name: userName } = user; // 重命名
const {
a: { b },
} = { a: { b: 1 } }; // 嵌套解构
// 函数参数解构
function greet({ name, age = 18 } = {}) {
return `${name} is ${age}`;
}
// 交换变量
let p = 1,
q = 2;
[p, q] = [q, p];
5. 默认参数
function createUser(name = "Anonymous", role = "user", active = true) {
return { name, role, active };
}
// 默认值可以是表达式或函数调用
function fn(a, b = a * 2) {
return b;
}
6. Rest / Spread 运算符
// Rest:收集剩余参数
function sum(...nums) {
return nums.reduce((a, b) => a + b, 0);
}
// Spread:展开数组/对象
const arr = [...arr1, ...arr2, 4, 5];
Math.max(...[1, 2, 3]);
const obj = { ...defaults, ...overrides, extra: true };
7. 类 (Class)
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound.`;
}
static create(name) {
// 静态方法
return new Animal(name);
}
get info() {
// getter
return `[${this.name}]`;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 必须先调用 super
this.breed = breed;
}
speak() {
return super.speak() + " Woof!";
}
}
8. 模块 (Modules)
// math.js — 导出
export const PI = 3.14159;
export function add(a, b) { return a + b; }
export default class Calculator { ... }
// main.js — 导入
import Calculator, { PI, add } from './math.js';
import * as MathLib from './math.js';
import './side-effect.js'; // 只执行副作用
9. Promise
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve("done"), 1000);
});
p.then((val) => console.log(val))
.catch((err) => console.error(err))
.finally(() => console.log("always runs"));
// 组合
Promise.all([p1, p2, p3]); // 全部成功才 resolve
Promise.race([p1, p2]); // 第一个完成(无论成功/失败)
10. Symbol
const id = Symbol('id'); // 唯一标识符
const obj = { [id]: 123 }; // 作为属性键,不会被枚举
// 内置 Symbol
class MyArray {
[Symbol.iterator]() { ... } // 自定义迭代行为
}
11. Map / Set / WeakMap / WeakSet
// Set — 值的集合,自动去重
const set = new Set([1, 2, 2, 3]);
set.add(4);
set.has(2); // true
set.delete(1);
set.size; // 3
// Map — 任意类型的键值对
const map = new Map();
map.set({ key: 1 }, 'object key');
map.set('str', 42);
map.get('str'); // 42
for (const [k, v] of map) { ... }
// WeakMap / WeakSet — 弱引用,不阻止 GC,键必须是对象
const cache = new WeakMap();
cache.set(domElement, { data: '...' });
12. 迭代器 / Generator
// 迭代器协议
const range = {
[Symbol.iterator]() {
let i = 0;
return {
next() {
return i < 3 ? { value: i++, done: false } : { done: true };
},
};
},
};
for (const n of range) console.log(n); // 0 1 2
// Generator 函数
function* gen() {
yield 1;
yield 2;
return 3;
}
const g = gen();
g.next(); // { value: 1, done: false }
// 无限序列
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
13. Proxy / Reflect
const handler = {
get(target, key) {
return key in target ? target[key] : `Key "${key}" not found`;
},
set(target, key, value) {
if (typeof value !== "number") throw new TypeError("Only numbers!");
target[key] = value;
return true;
},
};
const proxy = new Proxy({}, handler);
proxy.a = 42;
proxy.b; // "Key "b" not found"
// Reflect — 对应 Proxy 每个 trap 的默认行为
Reflect.get(target, key);
Reflect.set(target, key, value);
14. 新增数组方法
Array.from("abc"); // ['a', 'b', 'c']
Array.from({ length: 3 }, (_, i) => i); // [0, 1, 2]
Array.of(1, 2, 3); // [1, 2, 3]
[1, 2, 3].find((n) => n > 1); // 2
[1, 2, 3].findIndex((n) => n > 1); // 1
[1, 2, 3].fill(0, 1, 2); // [1, 0, 3]
[1, 2, 3].includes(2); // ES2016,见下文
// 迭代
for (const [i, v] of ["a", "b"].entries()) {
}
for (const k of ["a", "b"].keys()) {
}
for (const v of ["a", "b"].values()) {
}
15. 新增字符串方法
"hello".includes("ell"); // true
"hello".startsWith("he"); // true
"hello".endsWith("lo"); // true
"ha".repeat(3); // 'hahaha'
16. 对象简写 / 计算属性名
const x = 1,
y = 2;
const point = { x, y }; // 等同于 { x: x, y: y }
const key = "name";
const obj = {
[key]: "Alice", // 计算属性名
["key_" + 1]: "dynamic",
greet() {
return "hi";
}, // 方法简写
};
17. Object.assign
const target = { a: 1 };
Object.assign(target, { b: 2 }, { c: 3 });
// { a: 1, b: 2, c: 3 } — 浅拷贝
ES2016 (ES7)
1. Array.prototype.includes
[1, 2, NaN].includes(NaN); // true(比 indexOf 更准确)
[1, 2, 3].includes(2, 1); // true,从索引 1 开始搜索
2. 指数运算符 **
2 ** 10; // 1024
2 ** 0.5; // Math.sqrt(2)
let n = 2;
n **= 3; // 8
ES2017 (ES8)
1. async / await
async function fetchUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
const user = await res.json();
return user;
} catch (err) {
console.error(err);
}
}
// 并行执行
async function loadAll() {
const [users, posts] = await Promise.all([fetchUsers(), fetchPosts()]);
}
2. Object.values / Object.entries
const obj = { a: 1, b: 2, c: 3 };
Object.values(obj); // [1, 2, 3]
Object.entries(obj); // [['a',1], ['b',2], ['c',3]]
for (const [key, val] of Object.entries(obj)) {
}
3. Object.getOwnPropertyDescriptors
const descriptors = Object.getOwnPropertyDescriptors(obj);
// 用于完整克隆(含 getter/setter)
const clone = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj),
);
4. String.padStart / padEnd
"5".padStart(3, "0"); // '005'
"hi".padEnd(5, "."); // 'hi...'
String(42).padStart(6); // ' 42'(默认空格)
5. 函数参数/调用末尾逗号
function fn(
a,
b,
c, // ← 允许末尾逗号
) {}
fn(1, 2, 3);
6. SharedArrayBuffer / Atomics
// 多线程间共享内存
const sab = new SharedArrayBuffer(1024);
const arr = new Int32Array(sab);
// 原子操作(线程安全)
Atomics.add(arr, 0, 5);
Atomics.load(arr, 0); // 5
Atomics.wait(arr, 0, 5); // 等待直到值不为 5
ES2018 (ES9)
1. 对象 Rest / Spread
const { a, b, ...rest } = { a: 1, b: 2, c: 3, d: 4 };
// rest = { c: 3, d: 4 }
const merged = { ...obj1, ...obj2, extra: true };
2. 异步迭代 for await...of
async function processStream(stream) {
for await (const chunk of stream) {
process(chunk);
}
}
// 自定义异步可迭代
async function* asyncRange(start, end) {
for (let i = start; i <= end; i++) {
await delay(100);
yield i;
}
}
3. Promise.finally
fetch("/api/data")
.then(handleData)
.catch(handleError)
.finally(() => hideLoadingSpinner()); // 总会执行
4. RegExp 增强
// 命名捕获组
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const { year, month, day } = "2024-01-15".match(re).groups;
// lookbehind 断言
/(?<=\$)\d+/.exec("$100"); // ['100'] — 前面是 $
/(?<!\$)\d+/.exec("€100"); // ['100'] — 前面不是 $
// dotAll 模式(s 标志),. 可匹配换行
/hello.world/s.test("hello\nworld"); // true
// Unicode 属性转义
/\p{Script=Han}/u.test("汉"); // true — 汉字
/\p{Emoji}/u.test("🎉"); // true
ES2019 (ES10)
1. Array.flat / flatMap
[1, [2, [3, [4]]]].flat(); // [1, 2, [3, [4]]],默认深度 1
[1, [2, [3, [4]]]].flat(Infinity); // [1, 2, 3, 4]
// flatMap = map + flat(1),性能更好
["hello world", "foo bar"].flatMap((str) => str.split(" ")); // ['hello', 'world', 'foo', 'bar']
2. Object.fromEntries
// entries 转回对象
const entries = [
["a", 1],
["b", 2],
];
Object.fromEntries(entries); // { a: 1, b: 2 }
// Map 转对象
Object.fromEntries(map);
// 对象变换
const doubled = Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k, v * 2]),
);
3. String.trimStart / trimEnd
" hello ".trimStart(); // 'hello '
" hello ".trimEnd(); // ' hello'
// trimLeft/trimRight 是别名(非标准)
4. 可选的 catch 绑定
// 不需要捕获错误对象时,可省略参数
try {
JSON.parse(str);
} catch {
// 不再强制写 catch(e)
return false;
}
5. Symbol.description
const sym = Symbol("my symbol");
sym.description; // 'my symbol'(之前只能 toString())
6. Array.sort 稳定性保证
相同元素排序后,原始顺序保持不变(V8 之前对大数组不稳定)。
ES2020 (ES11)
1. BigInt
const big = 9007199254740993n; // 字面量加 n
const fromStr = BigInt("9007199254740993");
big + 1n; // 运算两侧都必须是 BigInt
Number(big); // 转换(可能丢精度)
typeof big; // 'bigint'
// 适合场景:大整数计算、密码学、数据库 ID
2. 可选链 ?.
user?.profile?.avatar?.url; // 任一层为 null/undefined 则返回 undefined
arr?.[0]; // 数组元素
fn?.(); // 函数调用(fn 不存在时不报错)
// 替代
const url =
user && user.profile && user.profile.avatar && user.profile.avatar.url;
3. 空值合并 ??
const name = user.name ?? "Anonymous"; // 仅 null/undefined 时取右值
const count = data.count ?? 0;
// 区别于 ||
0 || "default"; // 'default'(0 是 falsy)
0 ?? "default"; // 0(0 不是 null/undefined)
4. Promise.allSettled
const results = await Promise.allSettled([p1, p2, p3]);
// 不管成功失败,等所有完成
results.forEach(({ status, value, reason }) => {
if (status === "fulfilled") console.log(value);
else console.error(reason);
});
5. globalThis
// 跨环境获取全局对象
// 浏览器: window, Node.js: global, Worker: self
globalThis.setTimeout(() => {}, 0);
globalThis.fetch("/api");
6. 动态 import()
// 按需加载,返回 Promise
const { add } = await import("./math.js");
// 条件加载
if (needsChart) {
const Chart = await import("./chart.js");
}
// 路由懒加载
const routes = {
"/home": () => import("./pages/Home.js"),
};
7. String.matchAll
const str = "test1 test2 test3";
const re = /test(\d)/g;
// 返回迭代器,包含所有匹配及捕获组
for (const match of str.matchAll(re)) {
console.log(match[0], match[1], match.index);
}
// test1 1 0
// test2 2 6
// test3 3 12
8. import.meta
// 当前模块的元信息
console.log(import.meta.url); // 当前模块的 URL
console.log(import.meta.env); // 构建工具注入的环境变量(Vite 等)
ES2021 (ES12)
1. String.replaceAll
"a-b-c-d".replaceAll("-", "_"); // 'a_b_c_d'
// 之前需要:'a-b-c-d'.replace(/-/g, '_')
2. Promise.any
// 只要有一个 resolve 就成功;全部 reject 才抛出 AggregateError
const first = await Promise.any([slowP, fastP, failP]);
3. AggregateError
try {
await Promise.any([p1, p2]);
} catch (err) {
if (err instanceof AggregateError) {
err.errors; // 所有失败的原因数组
}
}
4. 逻辑赋值运算符
// &&= 只在左值为真时赋值
user.name &&= user.name.trim();
// ||= 只在左值为假时赋值
config.timeout ||= 3000;
// ??= 只在左值为 null/undefined 时赋值
user.role ??= "guest";
5. 数字分隔符 _
const billion = 1_000_000_000;
const bytes = 0xff_ec_d5_12;
const pi = 3.141_592_653;
const bits = 0b1010_0001;
6. WeakRef / FinalizationRegistry
// WeakRef — 弱引用,不阻止 GC
const ref = new WeakRef(someObject);
const obj = ref.deref(); // 可能已被回收,返回 undefined
// FinalizationRegistry — 对象被 GC 后执行回调
const registry = new FinalizationRegistry((heldValue) => {
console.log(`${heldValue} was collected`);
});
registry.register(obj, "myObject");
ES2022 (ES13)
1. 类私有字段和方法
class Counter {
#count = 0; // 私有字段
#step;
constructor(step = 1) {
this.#step = step;
}
#validate() {
// 私有方法
return this.#count >= 0;
}
increment() {
this.#count += this.#step;
}
get value() {
return this.#count;
}
static #instances = 0; // 静态私有字段
static getInstances() {
return Counter.#instances;
}
}
// 检查私有字段是否存在
#count in obj; // true/false
2. 静态类块 (Static Class Blocks)
class Config {
static debug;
static verbose;
static {
// 静态初始化块,可执行复杂逻辑
const env = getEnvironment();
Config.debug = env === "development";
Config.verbose = env !== "production";
}
}
3. Top-level await
// 在模块顶层直接使用 await(无需 async 函数包裹)
const data = await fetch("/api/config").then((r) => r.json());
const { default: lodash } = await import("lodash");
export const config = data;
4. Array/String/TypedArray.at()
const arr = [1, 2, 3, 4, 5];
arr.at(0); // 1
arr.at(-1); // 5(倒数第一)
arr.at(-2); // 4
"hello".at(-1); // 'o'
5. Object.hasOwn
// 替代 Object.prototype.hasOwnProperty.call(obj, key)
Object.hasOwn({ a: 1 }, "a"); // true
Object.hasOwn({ a: 1 }, "b"); // false
// 对 Object.create(null) 创建的对象也安全
const obj = Object.create(null);
Object.hasOwn(obj, "key"); // false(不会报错)
6. Error.cause
try {
await fetchData();
} catch (err) {
throw new Error('Failed to load user', { cause: err });
}
// 捕获时
try { ... } catch (err) {
console.log(err.cause); // 原始错误
}
7. RegExp d 标志(匹配下标)
const re = /(\d+)/d;
const match = "2024-01-15".match(re);
match.indices[0]; // [0, 4] — 整个匹配的起止索引
match.indices[1]; // [0, 4] — 第一个捕获组的起止索引
ES2023 (ES14)
1. Array findLast / findLastIndex
[1, 2, 3, 4].findLast((n) => n % 2 === 0); // 4(从右往左)
[1, 2, 3, 4].findLastIndex((n) => n % 2 === 0); // 3
2. 不可变数组方法(Immutable Array Methods)
const arr = [3, 1, 2];
arr.toSorted(); // [1, 2, 3],原数组不变
arr.toReversed(); // [2, 1, 3],原数组不变
arr.toSpliced(1, 1, 9); // [3, 9, 2],原数组不变
arr.with(0, 99); // [99, 1, 2],替换指定索引,原数组不变
// 对比破坏性方法
arr.sort(); // 修改原数组
arr.reverse(); // 修改原数组
3. Symbol 作为 WeakMap 键
const key = Symbol("key");
const map = new WeakMap();
map.set(key, { data: "value" }); // 之前只允许对象
4. Hashbang 语法
#!/usr/bin/env node
// 文件第一行的 #! 注释,用于 Unix 脚本
console.log("Hello");
ES2024 (ES15)
1. Promise.withResolvers
// 将 resolve/reject 暴露到 Promise 外部
const { promise, resolve, reject } = Promise.withResolvers();
// 之前需要
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
// 实际用途:事件驱动场景
function waitForClick(button) {
const { promise, resolve } = Promise.withResolvers();
button.addEventListener("click", resolve, { once: true });
return promise;
}
2. Object.groupBy / Map.groupBy
const people = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 17 },
{ name: "Carol", age: 30 },
];
// 按条件分组,返回普通对象
const grouped = Object.groupBy(people, (p) =>
p.age >= 18 ? "adult" : "minor",
);
// { adult: [...], minor: [...] }
// Map.groupBy — 键可以是任意值
const map = Map.groupBy(people, (p) => p.age >= 18);
// Map { true => [...], false => [...] }
3. String.isWellFormed / toWellFormed
// 检测/修复孤立代理字符(Lone Surrogate)
"\uD800".isWellFormed(); // false — 孤立代理项
"hello".isWellFormed(); // true
"\uD800".toWellFormed(); // ' ' (替换为 U+FFFD)
// 在 URL 编码、序列化场景中很有用
4. RegExp v 标志(集合操作)
// v 标志:Unicode 集合操作,更精确的字符类
/[\p{Letter}--\p{ASCII}]/v; // 非 ASCII 字母(差集 --)
/[\p{Letter}&&\p{ASCII}]/v; // ASCII 字母(交集 &&)
/[a-z[A-Z]]/v; // 嵌套字符类(集合并集)
/^[\p{Emoji_Keycap_Sequence}]$/v.test("1️⃣"); // true
5. ArrayBuffer resize / transfer
// 可调整大小的 ArrayBuffer
const buf = new ArrayBuffer(8, { maxByteLength: 16 });
buf.resize(12); // 调整为 12 字节
buf.byteLength; // 12
// 转移所有权(原 buffer 变为 detached)
const newBuf = buf.transfer();
const resized = buf.transfer(4); // 转移并调整大小
6. Atomics.waitAsync
// 非阻塞的异步等待(可在主线程使用)
const result = await Atomics.waitAsync(sharedArray, 0, 0).value;
// 当 sharedArray[0] 不再是 0 时 resolve
ES2025 (ES16)
1. Iterator Helpers(迭代器辅助方法)
// 所有迭代器现在都有这些方法
function* range(start, end) {
for (let i = start; i <= end; i++) yield i;
}
const iter = range(1, 10);
iter
.map((x) => x * 2) // 映射
.filter((x) => x > 6) // 过滤
.take(3) // 取前 N 个
.toArray(); // 收集为数组 → [8, 10, 12]
// 更多方法
iter.drop(2); // 跳过前 N 个
iter.flatMap((x) => [x, -x]); // 展平映射
iter.reduce((a, b) => a + b, 0);
iter.forEach((x) => console.log(x));
iter.some((x) => x > 5);
iter.every((x) => x > 0);
iter.find((x) => x > 5);
Iterator.from(arrayOrIterable); // 包装为迭代器
2. Set 方法
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
a.union(b); // {1,2,3,4,5,6} — 并集
a.intersection(b); // {3,4} — 交集
a.difference(b); // {1,2} — 差集 (a - b)
a.symmetricDifference(b); // {1,2,5,6} — 对称差集
a.isSubsetOf(b); // false — a 是否是 b 的子集
a.isSupersetOf(b); // false — a 是否是 b 的超集
a.isDisjointFrom(b); // false — a 和 b 是否不相交
3. Import Attributes(导入属性)
// 明确声明导入资源的类型
import data from "./data.json" with { type: "json" };
import sheet from "./styles.css" with { type: "css" };
// 动态导入
const mod = await import("./data.json", { with: { type: "json" } });
4. RegExp 重复命名捕获组
// 同一个命名可以出现在多个分支中
const re = /(?<year>\d{4})-(?<month>\d{2})|(?<month>\d{2})\/(?<year>\d{4})/;
"01/2024".match(re).groups; // { year: '2024', month: '01' }
"2024-01".match(re).groups; // { year: '2024', month: '01' }
5. Float16Array
// 16 位半精度浮点数,节省内存(机器学习、图形处理)
const f16 = new Float16Array([1.5, 2.5, 3.14]);
f16[0]; // 1.5
// 辅助函数
Math.f16round(1.337); // 四舍五入到最近的 float16
6. Promise.try
// 统一处理同步和异步函数,总返回 Promise
Promise.try(() => JSON.parse(str))
.then((data) => use(data))
.catch((err) => console.error(err)); // 捕获同步和异步错误
// 替代之前的
Promise.resolve().then(() => JSON.parse(str));
特性速查表
| 特性 | 版本 | 一句话 |
|---|---|---|
| let/const | ES6 | 块级作用域变量 |
| 箭头函数 | ES6 | 简洁函数 + 继承 this |
| 模板字符串 | ES6 | 字符串插值 |
| 解构赋值 | ES6 | 快速提取值 |
| 默认参数 | ES6 | 函数参数默认值 |
| Rest/Spread | ES6 | 收集/展开 |
| Class | ES6 | 面向对象语法 |
| Modules | ES6 | import/export |
| Promise | ES6 | 异步处理 |
| Symbol | ES6 | 唯一值类型 |
| Map/Set | ES6 | 新数据结构 |
| Generator | ES6 | 可暂停函数 |
| Proxy/Reflect | ES6 | 元编程 |
| Array.includes | ES7 | 包含检测 |
** |
ES7 | 指数运算符 |
| async/await | ES8 | 同步风格异步 |
| Object.entries | ES8 | 对象转 entries |
| padStart/End | ES8 | 字符串填充 |
| 对象 Rest/Spread | ES9 | {...obj} |
| for await...of | ES9 | 异步迭代 |
| Promise.finally | ES9 | 总会执行的回调 |
| RegExp 命名组 | ES9 | (?<name>...) |
| Array.flat | ES10 | 扁平化数组 |
| Object.fromEntries | ES10 | entries 转对象 |
| trimStart/End | ES10 | 去首/尾空格 |
| 可选 catch | ES10 | catch 省略参数 |
| BigInt | ES11 | 大整数 |
可选链 ?. |
ES11 | 安全访问属性 |
空值合并 ?? |
ES11 | null 默认值 |
| Promise.allSettled | ES11 | 等全部完成 |
| globalThis | ES11 | 跨环境全局对象 |
| 动态 import() | ES11 | 按需加载 |
| matchAll | ES11 | 所有正则匹配 |
| replaceAll | ES12 | 替换所有 |
| Promise.any | ES12 | 任一成功 |
| 逻辑赋值 | ES12 | &&= \|\|= ??= |
| 数字分隔符 | ES12 | 1_000_000 |
| 私有字段 | ES13 | #field |
| 静态类块 | ES13 | static { } |
| Top-level await | ES13 | 模块顶层 await |
| Array.at() | ES13 | 支持负索引 |
| Object.hasOwn | ES13 | 安全 hasOwnProperty |
| Error.cause | ES13 | 错误链 |
| findLast | ES14 | 从右查找 |
| toSorted/Reversed | ES14 | 不可变排序/反转 |
| Promise.withResolvers | ES15 | 暴露 resolve/reject |
| Object.groupBy | ES15 | 分组 |
| isWellFormed | ES15 | 检测代理字符 |
| Set 集合方法 | ES16 | 交/并/差集 |
| Iterator Helpers | ES16 | 迭代器链式操作 |
| Import Attributes | ES16 | with { type } |
| Float16Array | ES16 | 半精度浮点数组 |
| Promise.try | ES16 | 统一同步/异步 |