# ES2021 - 新特性

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

主要特性:

  • 逻辑赋值运算符
  • 数字分隔符
  • Promise.any & AggregateError
  • String.prototype.replaceAll
  • WeakRefs & FinalizationRegistry 对象

# 逻辑赋值运算符

逻辑赋值运算符结合逻辑运算符和赋值运算符,它让代码变得简短、让变量和对象属性条件赋值变得简单。

||=  // 结合 OR 逻辑运算符
&&=  // 结合 AND 逻辑运算符
??=  // 结合空值合并操作符
1
2
3

栗子:

// 旧
let a = null;
a = a || 'A'; // A
a = a && 'B'; // B
a = a ?? 'C'; // B

// 新
let b = null;
b ??= 'A'; // A
b &&= 'B'; // B
b ||= 'C'; // B
1
2
3
4
5
6
7
8
9
10
11

补充:空值合并操作符,只有当左侧的值是 null 或者 undefined 时,才会返回右侧的值。左侧支持 ''0 这样的假值。不能与 AND 或 OR 逻辑运算符共用

# 数字分隔符

允许数值字面量中间包含不连续 _,以提高可读性。

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

Number(1_1); // 11
Number('1_1'); // NaN
1
2
3
4
5
6
7

注意:分隔符不能在尾部和头部,只能在数字中间,只允许一个下划线作为数字分隔符,不可连续。字符串转数值时不支持。

# Promise.any

Promise.any 接受 Promise 对象数组作为参数,返回成功的 Promise 或者失败的 PromiseAggregateError 类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。只要给定的参数中的有一个 Promise 成功,就返回第一个 Promise 的值。

const pErr = new Promise((resolve, reject) => {
  reject("总是失败");
});

const pSlow = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "最终完成");
});

const pFast = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "很快完成");
});

Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
  // pFast fulfils first
});
// 输出: "很快完成"

Promise.any([pErr]).catch((err) => {
  console.log(err);
})
// 输出: "AggregateError: No Promise in Promise.any was resolved"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Promise.race:总是返回第一个 Promise (不管成功 or 失败)。

# String.prototype.replaceAll

String.prototype.replaceAll:字符串中所有满足 patern 的部分都会被替换。相比于 replace,不需要使用全局正则表达式了。

'hello world'.replaceAll('o', '_'); // hell_ w_rld

'hello world'.replace(/o/g, '_'); // hell_ w_rld
1
2
3

# WeakRef & FinalizationRegistry

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

WeakRef 提案主要包含两个新功能:

  • 可以通过 WeakRef 类来给某个对象创建一个弱引用
  • 可以通过 FinalizationRegistry 类,在某个对象被垃圾回收之后,执行一些自定义方法

一个 WeakRef 对象包含一个对于某个对象的弱引用,通过弱引用一个对象,可以让该对象在没有其它引用的情况下被垃圾回收机制回收。WeakRef 主要用来缓存和映射一些大型对象,当你希望某个对象在不被其它地方引用的情况下及时地被垃圾回收,那么你就可以使用它。

注意:正确使用它们需要仔细考虑,如果可能,最好避免使用它们。

FinalizationRegistry 接收一个回调函数,返回一个注册器,可以利用该注册器为指定对象注册一个事件监听器,当这个对象被垃圾回收之后,会触发监听的事件。

const registry = new FinalizationRegistry((heldValue) => {
  // ....
});
// 接着注册一个指定对象,同时也可以给注册器回调传递一些参数:
let theObject;
registry.register(theObject, "some value", theObject);
// 用指定对象取消监听
registry.unregister(theObject);
1
2
3
4
5
6
7
8
上次更新: 8/6/2021, 3:37:11 PM