1030 字
5 分钟
ES2021新特性

2021 年 6 月 22 日,第 121 届 Ecma 国际(Ecma International)大会以远程会议形式召开。正式通过了 ES2021 标准。

这次又带来了哪些有趣的特性呢?让我们一起来了解下。

String.prototype.replaceAll()#

相比于String.prototype.replace(),如果不使用全局正则表达式,就无法替换字符串中子字符串的所有实例。只会替换第一次匹配的字符。现在可以用String.prototype.replaceAll()替换全部字符串而不需要使用正则。

let str = "mike name is mike";

str.replace("mike", "tom"); // tom name is mike

str.replace(/mike/g, "tom"); // tom name is tom

str.replaceAll("mike", "tom"); // 🆕 tom name is tom

Promise.any()#

当有任何一个 promise 状态变为成功 (fulfilled),就返回。当全部 promise 都 rejected,抛出一个 AggregateError 错误。

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("p1"), 100);
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("p2"), 200);
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve("p3"), 300);
});
Promise.any([p1, p2, p3])
  .then((first) => {
    // 任何一个promise完成(fulfilled),就返回
    console.log(first);
  })
  .catch((error) => {
    // 全部promise都rejected,抛出一个AggregateError错误
    console.log(error);
  });

相似的 API

名字描述
Promise.allSettled不会短路ES2020
Promise.all当有一个 rejected 就短路ES2015
Promise.race当有一个 rejected 或 fulfilled 就短路ES2015
Promise.any当有一个 fulfilled 就短路ES2021

WeakRefs#

一般来说,在 JavaScript 中,对象的引用是强引用的,这意味着只要持有对象的引用,它就不会被垃圾回收。只有当该对象没有任何的强引用时, js 引擎垃圾回收器才会销毁该对象并且回收该对象所占的内存空间。

let obj = { a: 1, b: 2 }; // 只要我们访问 obj 对象,这个对象就不会被垃圾回收

但是 WeakRefs 可以创建一个弱引用,对象的弱引用是指当该对象应该被 js 引擎垃圾回收器回收时不会阻止垃圾回收器的回收行为。

weak_ref 实例具有一个方法 deref,该方法返回被引用的原始对象,如果原始对象已被回收,则返回 undefined 对象。

const weak_ref = new WeakRef({ name: "tom" });
let obj = weak_ref.deref();
if (obj) {
  console.log(obj.name); // tom
}
CAUTION

使用它们需要仔细考虑,尽量避免使用它们。

FinalizationRegistry 使用 FinalizationRegistry 对象可以在垃圾回收器回收对象时执行回调函数。

// 构建监听对象被垃圾回收器清除的回调
const fr = new FinalizationRegistry((heldValue) => {
  console.log(heldValue);
});

const obj = {};
const token = {};

/**
 * @function 注册监听
 * @param 需要监听的对象
 * @param 需要合并的Grid
 * @param 取消监听用的标识符
 */
fr.register(obj, "obj deleted!", token);

/**
 * @function 取消监听
 * @param 取消监听的对象
 */
fr.unregister(token);

// 可能很久以后,回调执行
// => obj deleted!

数值分割符#

引入的数值分隔符使用_(下划线)字符,在数值组之间提供分隔,提高数字的可读性。

let num1 = 1000000000; // 1000000000

let num2 = 1_000_000_000; // 🆕  1000000000

console.log(num1 === num2); // true

let a = 1_1; // 11
let a = 1__1 // 错误,只允许一个下划线作为数字分隔符
let a = 1_;  // 错误,分隔符不能在尾部
let a = _1;  // 错误,分隔符不能在头部

Number(1_1); // 11
Number('1_1'); // NaN
CAUTION

分隔符不能在尾部和头部,只能在数字之间,只允许一个下划线作为数字分隔符,不可连续。分隔符不影响数值的类型转换值,也无法在字符串转数值时被识别。

逻辑赋值运算符#

逻辑赋值运算符,目的是提供简洁的写法。

a ||= b;
// 等效于以下两种写法
// a || (a = b); a为false时执行右边
// if(!a) a = b;

a &&= b;
// 等效于以下两种写法
// a && (a = b); a为truth时执行右边
// if(a) a = b

a ??= b;
// 等效于以下两种写法
// a ?? (a = b); a为undefined或null时执行右边
// if(a === nudefined || a === null) a = b;

其中?? 运算符只有左边是 undefined 或 null 才返回右边。

undefined ?? 1; // 1
null ?? 1; // 1
false ?? 1; // false
0 ?? 1; // 0
"" ?? 1; // ""
NaN ?? 1; // NaN
2 ?? 1; // 2
ES2021新特性
https://ameng404.com/posts/javascript/es2021/
作者
Ameng
发布于
2022-12-01
许可协议
CC BY-NC-SA 4.0