Skip to content

ECMAScript 2021 (12)

特性一览

逻辑赋值运算符

逻辑与赋值(&&=): 运算仅在 x 为真值时为其赋值。

js
let a = 1;
let b = 0;

a &&= 2;
console.log(a); // 2

b &&= 2;
console.log(b); //0

逻辑或赋值(||=): 运算仅在 x 为假值时为其赋值。

js
const a = { duration: 50, title: "" };

a.duration ||= 10;
a.duration; // 50

a.title ||= "title is empty.";
a.title; // "title is empty"

逻辑空赋值(??=): 仅在 x 是空值(null 或 undefined)时对其赋值。

js
const a = { duration: 50 };

a.duration ??= 10;
a.duration; // 50

a.speed ??= 25;
a.speed; // 25

数字分隔符

允许在数字字面量中使用下划线(_)来分隔数字,方便阅读和理解。

数字字面量分隔符不会影响数字的值,只是在语法上提供了一种分隔数字的方式。在数字被解析后,下划线将被忽略,数字的值将与没有下划线的数字相同。

js
const a = 1_2_3;
a; // 123

String.replaceAll()

替换字符串中的指定内容

js
const p =
  "The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?";

p.replaceAll("dog", "monkey"); // "The quick brown fox jumps over the lazy monkey. If the monkey reacted, was it really lazy?"

支持正则表达式

js
const regex = /Dog/gi;
p.replaceAll(regex, "ferret"); // "The quick brown fox jumps over the lazy ferret. If the ferret reacted, was it really lazy?"

AggregateError

该错误对象用于表示多个错误。

在错误处理中使用 AggregateError 可以提高代码的可读性和可维护性。它还可以在重新抛出多个错误时(比如在 Promise.allSettled 中),提高错误信息的清晰度。

  • 捕获一个 AggregateError
js
Promise.any([Promise.reject(new Error("some error"))]).catch((e) => {
  console.log(e instanceof AggregateError); // true
  console.log(e.message); // "All Promises rejected"
  console.log(e.name); // "AggregateError"
  console.log(e.errors); // [ Error: "some error" ]
});
  • 创建一个 AggregateError
js
try {
  throw new AggregateError([new Error("some error")], "Hello");
} catch (e) {
  console.log(e instanceof AggregateError); // true
  console.log(e.message); // "Hello"
  console.log(e.name); // "AggregateError"
  console.log(e.errors); // [ Error: "some error" ]
}

Promise.any()

Promise.any()是对 Promise.race()方法的扩展,它可以处理多个 Promise 的情况并在任意一个 Promise 完成时返回。

js
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve, reject) =>
  setTimeout(reject, 100, "error")
);
const promise3 = new Promise((resolve, reject) =>
  setTimeout(resolve, 200, "success")
);

Promise.any([promise1, promise2, promise3]).then((result) => {
  console.log(result); // 1
});

Promise.any()可以用于同时处理多个 Promise 实例,当至少有一个 Promise 变成 fulfilled 状态时,返回的 Promise 就会变为 fulfilled 状态,并返回该 Promise 的返回值。

javascript
const promises = [
  fetch("https://jsonplaceholder.typicode.com/todos/1").then((res) =>
    res.json()
  ),
  fetch("https://yes").then((res) => res.json()),
  fetch("https://no").then((res) => res.json()),
];

Promise.any(promises)
  .then((result) => {
    console.log("至少有一个Promise变成fulfilled状态:", result);
  })
  .catch((error) => {
    console.log("所有的Promise均为rejected状态:", error);
  });

而当所有 Promise 都被 rejected 时,Promise.any()返回的 Promise 就会变成 rejected 状态,并返回一个包含所有 rejected Promise 原因的 AggregateError 实例。

js
const p1 = Promise.reject("1st error");
const p2 = Promise.reject("2nd error");
const p3 = Promise.reject("3rd error");

Promise.any([p1, p2, p3])
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.log(error);
    console.log(error instanceof AggregateError);
    console.log(error.errors);
  });

WeakRef 和 FinalizationRegistry

  • FinalizationRegistry

在对象被垃圾回收时的回调函数。

js
const registry = new FinalizationRegistry((value) => {
  console.log(`${value}被回收`);
});

let person = { name: "baizhi958216" };

registry.register(person, "person");

// 过一段时间后会被销毁
person = null;
  • WeakRef

在强引用中,一个对象只要持有对象的引用,它就不会被垃圾回收。只有当该对象没有任何的强引用时,JavaScript 引擎 GC 才会销毁该对象并且回收该对象所占的内存空间。

js
const registry = new FinalizationRegistry((value) => {
  console.log(`${value}被回收`);
});
let person = { name: "baizhi958216" };
const people = { p1: person };
registry.register(person, "person");
// person没有被回收
person = null;

ECMAScript2021 提出的 WeakRef 允许对象在被引用的情况下进行垃圾回收。

js
const registry = new FinalizationRegistry((value) => {
  console.log(`${value}被回收`);
});
let person = { name: "baizhi958216" };
// 创建一个WeakRef
const people = new WeakRef({ p1: person });
registry.register(person, "person");
// 过一会提示person被回收
person = null;