2020-25 Js ES新增加特性

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 空值合并赋值:仅当 anullundefined 时,赋值 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]);
}
相关推荐
wanzhong23331 小时前
开发日记13-响应式变量
开发语言·前端·javascript·vue
代码游侠1 小时前
学习笔记——文件传输工具配置与Makefile详解
运维·前端·arm开发·笔记·学习
踢球的打工仔1 小时前
typescript-类的静态属性和静态方法
前端·javascript·typescript
C_心欲无痕1 小时前
Next.js Script 组件详解
开发语言·javascript·ecmascript·next.js
匠心网络科技1 小时前
前端框架-Vue双向绑定核心机制全解析
前端·javascript·vue.js·前端框架
Jinuss1 小时前
源码分析之React中的FiberRoot节点属性介绍
前端·javascript·react.js
2501_944526421 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 收藏功能实现
android·java·开发语言·javascript·python·flutter·游戏
2501_944526421 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 个人中心实现
android·java·javascript·python·flutter·游戏
wanzhong23331 小时前
开发日记14-vite配置多环境
服务器·前端·vue