ES2021新特性

1,415 阅读4分钟

ECMAScript 的新版本 ES2021 于 2021 年 6 月发布,我们可以期待新版本有哪些新特性?本文介绍了ES2021的版本中的一些功能,以及我们如何使用它们。

ES2021 主要有5个新特性:

  • String.prototype.replaceAll
  • 逻辑赋值运算符(Logical Assignment Operator)
  • 数字分隔符(Numeric Separators)
  • Promise.any
  • WeakRef

String.prototype.replaceAll

这可能是这个版本里最令我兴奋的功能。

如果使用之前的办法来替换字符串中所有出现的子字符串, replace()必须要结合全局正则表达式的方法来替换,这一方法已经成为业界主流的方式来使用。

现在,使用新方法replaceAll(),我们可以轻松返回一个新字符串,该字符串中的子字符串已经被全部替换,而无需使用复杂的正则表达式。

 const myString =
   "I love Cats. Cats are supercute, especially when they are doing Catstuff";
 ​
 let newString = myString.replaceAll("Cat", "Dog");
 ​
 console.log(newString);
 ​
 //I love Dogs. Dogs are supercute, especially when they are doing Dogstuff

此方法还带来了性能改进,因为该方法的内部实现是使用字符串比较,而不是正则表达式匹配。

逻辑赋值运算符 Logical Assignment Operator

逻辑赋值运算符结合了逻辑运算符 ( &&, ||, ??) 和赋值表达式 ( =)。

下面的代码示例显示了在运算符 AND ( &&)、OR ( ||) 和空合并运算符 ( ??)上使用的此功能。

 //Only assigns if left-hand side is Truthy
 //Old approach
 a && (a = b)
 ​
 //Logical assignment operator
 a &&= b
 ​
 //Only assigns if left hand-side is Falsy
 //Old approach
 a || (a = b)
 ​
 //Logical assignment operator
 a ||= b 
 ​
 //Only assigns if left hand side is Nullish
  (null / undefined)
 //Old approach
 a ?? (a = b)
 //Logical assignment operator
 a ??= b

下面我们用空值合并逻辑赋值运算符来举例子。

假设,我们有变量money。使用空合并运算符,money变量值为undefinednull时,会被赋值为defaultValue,否则就会被赋值为 money 本身:

 const defaultValue = 1;
 let money = null;
 ​
 money = money ?? defaultValue;

而使用逻辑赋值运算符,我们得到了一个稍微短一点的语法:

 money ??= defaultValue;

数字分隔符 Numeric Separators

大数字乍一看可能难以阅读,尤其是在有重复数字时。数字分隔符是一个有用的工具,它在数字中用下划线 (_)分隔数字,从而使长数字文字更具可读性。

分隔符可以用在不同的位置,可以使用任意数量的分隔符,以任意大小分组。也就是说,这里可以每4位分割一次,以万、亿为分割,方便中国人阅读

 const oneMillion = 1000000;
 // 千分位
 const oneMillionWithSeparators = 1_000_000;
 // 万分位
 const oneMillionWithSeparators = 100_0000;
 const oneMillionAndALittleMore = 1_000_000.123_456;

正如我们所见,代码变得更具可读性了。

另外,数字分隔符也适用于八进制整数文字。

Promise.any 和 AggregateError

简而言之,这个方法和Promise.all()类似。

Promise.any()接受一个可迭代的 Promise 对象数组,在数组中任意一个Promise resolve 时,即resolve。

考虑下面的示例,我们创建了三个 Promise 并将它们输入到Promise.any().

 const promise1 = new Promise((resolve) => setTimeout(resolve, 100, 'first'));
 const promise2 = new Promise((resolve) => setTimeout(resolve, 300, 'second'));
 const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'third'));
 ​
 const promises = [promise1, promise2, promise3];
 ​
 Promise.any(promises).then((value) => console.log(value));
 ​
 // Expected output: "first"

如果所有 Promise 都没有resolve,则会抛出一种新类型的异常AggregateErrorAggregateError将错误以对象数组的形式组合为一个错误数组。漂亮整齐!

弱引用 WeakRef

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

 var a, b;
 a = b = document.querySelector('.someClass')
 a = undefined
 // ... GarbageCollecting...
 // b is still references to the DOM-object .someClass

如果我们不想无限期地将对象保留在内存中,可以用WeakRef来实现缓存到大对象的映射。当不使用时,内存可以被垃圾收集并在再次需要时生成一个新的缓存。

WeakRef 用new WeakRef 来创建,用 .deref() 来读取。

 const x = new WeakRef(document.querySelector('.someClass'));
 const element = x.deref();

JavaScript 不断集成新功能,今天我们研究了 JavaScript ES2021 中的一些功能。有关提案的更多信息以及接下来会发生什么,请仔细查看此处