ES2020 ( ES11 ) Node ≥ v14.0.0。
1、可选链操作符 "?" node ≥ v14.0.0
前提条件:Node.js >= 14 +现代构建工具 ,或者有 Babel(升级到7.x +带插件)
功能:等同逻辑与(&&)
默认:通常2020之前项目默认构建环境是不支持的。
javascript
//通用 &&
const name = user && user.info && user.info.name;
//可选链操作符 ?
const name = user?.info?.name
2、空值合并操作符 "??" node ≥v14.0.0
仅对null 或 undefined 提供默认值
javascript
// '' 、 0、false 不会触发默认值
// 仅 input 为 null 或 undefined 时触发
const name = input ?? 'Anonymous';
3、BigInt node ≥v10.4.0
任意精度整数(超出 Number.MAX_SAFE_INITEER 的场景)
解决了Number 类型在处理超过安全整数范围(±2⁵³ - 1) 的整数时会失真的问题。
- 目的:任意大小整数,无精度损失。
- 限制:不能与 Number 混用、不支持 JSON、不支持 Math。
- 使用场景:大 ID、高精度整数计算、现代 API 交互
如何使用
注意:可传入整数 或整数字符串。!!!禁止小数或小数字符串
javascript
// number双精度浮点数 (±2⁵³ - 1)
const bigNum = 9007199254740991n;
// 注意末尾n
console.log(bigNum + 1n);
//9007199254740992n
//方法1:整数末尾+n
const big1 = 1234n;
const big2 = -5678n;
//方法2: 使用BigInt构造函数
const big3 = BigInt(123);
const big4 = BigInt('123');
4、globalThis node ≥ v12.0.0
统一获取全局对象(浏览器=window,Node.js = global)
javascript
// 2020 以前写法
const globalObj = typeof window !== 'undefined'? window : global;
// 现在
const globalObj = globalThis;
5、动态 import() node ≥ v12.20.0 / v13.2.0
运行时按需加载模块
ES2021 ( ES12) Node ≥ v15.0.0
⚠️ 兼容性提醒
- 浏览器:Chrome 85+、Firefox 79+、Safari 14+
- 在旧环境需用 Babel 转译(插件:@babel/plugin-proposal-logical-assignment-operators)
1、逻辑赋值运算符
- &&= : 仅当左值为真时赋值;
- ||= :仅当左值为假时赋值;
- ??= :仅当左值为null/undefined 时赋值。
javascript
//初始化赋值配置
config.debug ??= false;
user.name ||= 'guest';
2、replaceAll() 无需正则替换匹配项 node ≥ v15.0.0 v8+引擎
- str.prototype.replaceAll()
javascript
const str = 'apple,orange,banana';
str.replaceAll('orange', 'pineapple');
// 'apple,pineapple,banana'
3、Promise.any() node ≥ v15.0.0
✅ Promise.any(iterable) 返回一个 Promise,该 Promise 在输入的任意一个 Promise 成功(fulfilled) 时就立即以该 Promise 的值 resolve。
- 只要有一个 Promise 成功,整体就成功。
- 只有当 所有 Promise 都失败(rejected) 时,Promise.any() 才会 reject。
Promise.race():第一个 settled(无论成功或失败)的 Promise 决定结果。
Promise.any():第一个 成功的 Promise 决定结果;失败的会被忽略,直到全部失败。
javascript
const p1 = Promise.reject('Error 1');
const p2 = Promise.resolve('Success!');
const p3 = Promise.reject('Error 2');
Promise.any([p1, p2, p3])
.then(value => {
console.log(value); // 'Success!'
});
//即使 p1 和 p3 失败了,只要 p2 成功,Promise.any() 就 resolve。
4、逻辑赋值运算符 node ≥ v12.8.0+
| 运算符 | 全称等价写法 | 含义 |
|---|---|---|
| `a | = b` | |
a &&= b |
a = a && b |
逻辑 AND 赋值:仅当 a 为真值(truthy)时,赋值 b |
a ??= b |
a = a ?? b |
空值合并赋值:仅当 a 为 null 或 undefined 时,赋值 b |
💡 关键区别:
- ||= 关注 falsy 值(如 0, '', false, NaN, null, undefined)
- ??= 只关注 null / undefined(不把 0 或 '' 当作"空")
💡实际应用场景:
- 缓存初始化
javascript
let cache;
cache ??= new Map(); // 未定义是创建
- 用户配置合并
javascript
sys.settings.lang ?? = 'en';
- 避免重复DOM查询
javascript
let button;
button ??= document.querySelector('#submit-btn');
button?.addEventListener('click', func)
5、数字分隔符 _
提高可读性。适用于大数字或带小数的数值
数字的任意位置插入 _(但不能在开头、结尾或紧邻小数点)
javascript// 整数 const billion = 1_000_000_000; const million = 1_000_000; // 小数 const price = 123_456.789_012; // 二进制、十六进制等也支持 const binary = 0b1010_1101; const hex = 0xFF_EC_DE_23; const bigint = 1_000_000_000n;
ES2022 (ES13) Node ≥ 16.14.0
1、类字段声明 Class Fields node v14.6.0+
直接在class中定义属性和私有成员private fields。
- 在字段名字前加 # ,代表私有字段
javascript
class Person{
#count = 0; //私有字段
name = 'yema'; // 公有字段
constructor(name, age) {
this.name = name;
this.#count = age;
}
getCount() { // 公有方法
return this.#count;
}
setCount(newAge){
if (newAge > 0){
this.#count = newAge
}
}
}
const p = new Person('yema', 30);
console.log(p.name); // 'yema' 访问正确
console.log(p.#count); // 错误
console.log(p.getCount()) // 30 访问正确,通过公有方法间接访问
2、at() 方法(数组、字符串、TypedArray) node v16.6.0+
- 支持负索引。例如 str.at(-1) = str[str.length -1]
javascript
const arr = ['1213','2312','7','90']
const arr.at(-1); // '90'
'yema'.at(-2); // 'm'
3、 Object.hasOwn() Node v16.9.0+
用于安全检测对象自身是否拥有某个属性
基本语法:Object.hasOwn(obj, propKey) 替代 Object.prototype.hasOwnProperty.call()
优点:
- 不会被对象属性覆盖
- 适用所有对象(包括Object.create(null)创建对象)
javascript
//旧写法
//封装成函数--不报错的
function hasOwnProp(obj, prop){
return Object.prototype.hasOwnProperty.call(obj, prop);
}
// 弊端-被覆盖或者新创建的,找不到方法
const obj = { name: 'yema'}
obj.hasOwnProperty = null;
console.log(obj.hasOwnProperty('name'); // typeError
const newObj = Object.create(null);
newObj.name = 'yema';
newObj.hasOwnProperty('name');
// typeError newObj.hasOwnProperty is not a function;
//node16+ 新写法
const obj= Object.create(null);
obj.name = 'yema';
console.log(Object.hasOwn(obj, 'name'); // true
//封装函数
function safeCheck(obj, propKey){
return Object.hasOwn(obj, propKey)
}
4、Top-level await node v16.0.0+
在模块顶层直接使用 await(非函数内)
- 仅在 .mjs 或 package.json 设 "type": "module" 时可用
javascript
// 1. 私有字段
class Counter {
#count = 0;
increment() { this.#count++; }
}
// 2. .at() 方法
console.log([1, 2, 3].at(-1)); // 3
// 3. Object.hasOwn
console.log(Object.hasOwn({a:1}, 'a')); // true
// 4. Top-level await (需 ESM)
// await fetch('https://api.example.com');
// 5. Error cause
try {
throw new Error('Inner error');
} catch (err) {
throw new Error('Outer error', { cause: err });
}
ES2023(ES14) Node18.17+(LTS) 或 Node20+(Active LTS)
1、数组查找方法(findLask 元素对象、findLaskIndex 索引) node v18.17.0+
从末尾开始找匹配第一个
| 特性 | 说明 |
|---|---|
Array.prototype.findLast() |
从数组末尾向前查找第一个满足条件的元素 |
Array.prototype.findLastIndex() |
返回从末尾向前查找第一个满足条件的元素的索引 |
Hashbang v20.0.0(#!/usr/bin/env node) |
允许在 JS 文件顶部使用 shebang(主要用于可执行脚本) |
javascript
const arr = [{id:1}, {id:2}, {id:3},{id:4}];
arr.findLast(i => i.id > 2); // {id:4}
arr.findLastIndex(i => i.id >1); // 3
ES2024 (ES15) Node 22.0.0+
1、Set 新增方法
- set.intersection(otherSet) 交集
- set.union(otherSet) 并集
- set.difference(otherSet) 差集
- set.symmetricDifference(otherSet) 对称差集
- set.isSubsetOf(otherSet)
- set.isSupersetOf(otherSet)
- set.isDisjointFrom(otherSet)
javascript
const a = new Set([12,23,34,45,56,67,78]);
const b = new Set([34,45,56,67,89,90]);
console.log(a.intersection(b)) ; //交集 {34,45,56,67}
💡同样适用于 Map(如 map.groupBy() 等,但部分属于 Stage 3,ES15 正式纳入的是 Set 的集合操作方法)
2、ArrayGrouping(Object.groupBy 和 Map.groupBy)
- Object.groupBy(items, callback) → 返回分组对象 { key: [items] }
- Map.groupBy(items, callback) → 返回分组 Map
原生支持,无需lodash
javascript
const person = [
{ name:'name1', age: 18}
{ name:'name2', age: 20}
{ name:'name3', age: 21}
{ name:'name4', age: 40}
{ name:'name5', age: 32}
{ name:'name6', age: 33}
{ name:'name7', age: 36}
]
const byAge = Object.groupBy(person, ({age}) => age >21 ? 'big':'small');
// { big:[{...}], small: [{...}]}
3、Promise.withResolvers() 简化promise创建
javascript
//旧写法
let reject, resolve;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
})
//新写法
const { promise, resolve, reject } = Promise.withResolvers;
其他
1、遍历对象本身可枚举属性,方法推荐:
javascript
const user = { name: 'yema', age: 34, sex: '女'}
//方法1
Object.keys(user).forEach(key => { ...})
//方法2
for (const key in user) {
console.log(key, user[key]);
}