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变量值为undefined或null时,会被赋值为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,则会抛出一种新类型的异常AggregateError,AggregateError将错误以对象数组的形式组合为一个错误数组。漂亮整齐!
弱引用 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 中的一些功能。有关提案的更多信息以及接下来会发生什么,请仔细查看此处