ES12新特性了解下?

新增特性:

  • String.prototype.replaceAll
  • Promise.any
  • WeakRefs
  • 逻辑运算符和赋值表达式
  • 数字分隔符号

1.replaceAll

replaceAll返回一个全新的字符串,所有符合匹配规则的字符都将被替换掉,替换规则可以是字符串或者正则表达式

1
2
3
4
5
6
7
8
9
10
11
12
let string = 'I love 前端,I love 前端路漫漫'

//使用replace
let replaceStr = string.replace('love','hate')
console.log(replaceStr) // 'I hate 前端,I love 前端路漫漫'

//replace使用正则匹配所有
console.log(string.replace(/love/g,'hate')) // 'I hate 前端,I hate 前端路漫漫'

//使用replaceAll
let replaceAllStr = string.replaceAll('love','hate')
console.log(replaceAllStr) // 'I hate 前端,I hate 前端路漫漫'

需要注意的是,replaceAll在使用正则表达式的时候,如果非全局匹配(/g),则replaceAll()会抛出一个异常

2.Promise.any

当Promise列表中的任意一个promise成功resolve则返回第一个resolve的结果状态 如果所有的promise均reject,则抛出异常表示所有请求失败

1
2
3
4
5
6
7
8
9
10
Promise.any([
new Promise((resolve, reject) => setTimeout(reject, 500, '哎呀,我被拒绝了')),
new Promise((resolve, reject) => setTimeout(resolve, 1000, '哎呀,她接受我了')),
new Promise((resolve, reject) => setTimeout(resolve, 2000, '哎呀,她也接受我了')),
])
.then(value => console.log(`输出结果: ${value}`))
.catch (err => console.log(err))

//输出
//输出结果:哎呀,她接受我了

再来看下另一种情况

1
2
3
4
5
6
7
8
9
Promise.any([
Promise.reject('Error 1'),
Promise.reject('Error 2'),
Promise.reject('Error 3')
])
.then(value => console.log(`请求结果: ${value}`))
.catch (err => console.log(err))
//输出
AggregateError: All promises were rejected

Promise.any与Promise.race十分容易混淆,务必注意区分,Promise.race 一旦某个promise触发了resolve或者reject,就直接返回了该状态结果,并不在乎其成功或者失败

3.WeakRefs

使用WeakRefs的Class类创建对对象的弱引用(对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为)
注意:要尽量避免使用 WeakRefFinalizationRegistry,垃圾回收机制依赖于 JavaScript 引擎的实现,不同的引擎或是不同版本的引擎可能会有所不同。

这个提案主要包括两个主要的新功能:

  • 使用 WeakRef 类创建对象的弱引用
  • 使用 FinalizationRegistry 类对对象进行垃圾回收后,运行用户定义的终结器
    它们可以分开使用也可以一起使用。

WeakRef 实例不会阻止 GC 回收,但是 GC 会在两次 EventLoop 之间回收 WeakRef 实例。GC 回收后的 WeakRef 实例的 deref() 方法将会返回undefined

1
2
let ref = new WeakRef(obj)
let isLive = ref.deref() // 如果 obj 被垃圾回收了,那么 isLive 就是 undefined

FinalizationRegistry 注册 Callback,某个对象被 GC 回收后调用。

1
2
3
4
5
6
const registry = new FinalizationRegistry(heldValue => {
// ....
});

// 通过 register 注册任何你想要清理回调的对象,传入该对象和所含的值
registry.register(theObject, "some value");

4.逻辑运算符和赋值表达式

逻辑运算符和赋值表达式,新特性结合了逻辑运算符(&&,||,??)和赋值表达式而JavaScript已存在的 复合赋值运算符有:

  • 操作运算符:+= -= *= /= %= **=
  • 位操作运算符:&= ^= |=
  • 按位运算符:<<= >>= >>>=

回顾下 ES2020 新增的空值合并操作符 ??

在当左侧操作数为 undefinednull 时,该操作符会将右侧操作数赋值给左侧变量。

1
2
const name = null ?? '前端路漫漫'
console.log(name) // 前端路漫漫

逻辑赋值运算符写法:

1
2
3
4
5
a ||= b; // 等同于 a || (a = b);

a &&= b; // 等同于 a && (a = b);

a ??= b; // 等同于 a ?? (a = b);

5.数字分隔符

数字分隔符,可以在数字之间创建可视化分隔符,通过_下划线来分割数字,使数字更具可读性

1
2
3
4
5
6
7
const money = 1_000_000_000
//等价于
const money = 1000000000

const totalFee = 1000.12_34
//等价于
const totalFee = 1000.1234

该新特性同样支持在八进制数中使用

1
2
3
const number = 0o123_456
//等价于
const number = 0o123456