即将推出的值得关注的 JavaScript ES2021(ES12)功能

2025-06-08

即将推出的值得关注的 JavaScript ES2021(ES12)功能

ES2021(ES12)将于 2021 年中期发布。在本教程中,您将了解此规范中最有趣的五个特性:String.prototype.replaceAll()、数字分隔符、逻辑赋值运算符Promise.any()WeakRef和终结器。

关于功能的简要说明

您将在本文中阅读到的所有五个功能目前都处于第 4 阶段。这意味着它们已经完成,并准备好由 JavaScript 引擎实现。这也意味着您不必担心会浪费时间学习一些永远不会实现的东西。您不会的。

所有这些功能即将发布。如果您感兴趣,可以在Ecma TC39 官方 GitHub 仓库中了解更多其他提案。该仓库跟踪所有提案以及每个提案当前所处的阶段。现在,让我们来看看 ES2021 规范将带来哪些有趣的功能。

String.prototype.replaceAll()

让我们从 JavaScript ES2021 中一个较小的功能开始,但它仍然是语言的一个不错的补充,replaceAll()那就是方法。目前,当你想替换 [string] 中某个模式的多次出现时,可以使用replace() 方法。问题是什么?如果你使用字符串,这将只允许你替换该模式的第一次出现。

这并不意味着replace()如果你想替换所有出现的模式,该方法就没用。它也能完成这项工作。但是,你必须使用正则表达式。如果你觉得可以,那就没问题。对于许多开发人员来说,正则表达式并不是他们的首选。远非如此。

如果您是这些开发人员之一,您一定会喜欢这个新replaceAll()方法。此方法的工作方式与方法类似replace()。不同之处在于,它replaceAll()允许您替换所有出现的模式,而无需使用正则表达式。

replaceAll()方法也接受正则表达式。所以,如果你喜欢正则表达式,你也可以使用它。你也可以使用函数来替代它。如果这样做,这个函数会在字符串中的每个匹配项执行。你可以在官方仓库中阅读这个提案。

// Declare a string:
let str = 'There are those who like cats, there those who like watching cats and there are those who have cats.'

// Replace all occurrences of "cats" with dogs:
str = str.replaceAll('cats', 'dogs')

// Log the new value of "str":
console.log(str)
// Output:
// 'There are those who like dogs, there those who like watching dogs and there are those who have dogs.'


// A simple alternative with replace():
str = str.replace(/cats/g, 'dogs')

// Log the new value of "str":
console.log(str)
// Output:
// 'There are those who like dogs, there those who like watching dogs and there are those have dogs.'
Enter fullscreen mode Exit fullscreen mode

数字分隔符

这是 JavaScript ES2021 中另一个非常小的功能,但它至少能让你的工作效率提升一些。尤其是在处理大数字时。数字分隔符提供了一种简单易用的方法,让大数字更易读、更易于操作。它的语法也同样简单,就是一个下划线 ( _)。

// Number without numeric separators:
const num = 3685134689


// Number with numeric separators:
const num = 3_685_134_689
Enter fullscreen mode Exit fullscreen mode

请记住,数字分隔符只是视觉辅助。使用它们不会对数值本身产生任何影响。例如,如果您尝试使用数字分隔符记录数字,您将获得“原始”和“未编辑”的版本。

// Use numeric separators with a number:
const num = 3_685_134_689

// Log the value of "num":
console.log(num)
// Output:
// 3685134689
Enter fullscreen mode Exit fullscreen mode

逻辑赋值运算符

JavaScript 允许在布尔上下文中使用逻辑运算符。例如,在if...else 语句三元运算符中,用于测试真值。ES2021 和逻辑赋值运算符将改变这一规则。这些运算符允许你将逻辑运算符与赋值表达式 ( =) 结合使用。

您可以使用一些已经存在一段时间的赋值运算符+=。例如,加法赋值 ( )、减法赋值 ( -=)、乘法赋值 ( *=) 等等。得益于 ES2021,您还可以使用逻辑运算符 ( &&,||??(空值合并))。

//
// AND AND equals (&&=)
x &&= y

// Is equivalent to:
x = x && d

// Or:
if (x) {
  x = y
}

// Example 1:
let x = 3 // Truthy value.
let y = 0 // Falsy value.
x &&= y

// Log the value of "x":
console.log(x)
// Output:
// 0

// Example 2:
let x = 0 // Falsy value.
let y = 9 // Truthy value.
x &&= y

// Log the value of "x":
console.log(x)
// Output:
// 0

// Example 3:
let x = 3 // Truthy value.
let y = 15 // Truthy value.
x &&= y

// Log the value of "x":
console.log(x)
// Output:
// 15


//
// OR OR equals (||=):
x ||= y

// Is equivalent to:
x = x || y

// Or:
if (!x) {
  x = y
}

// Example 1:
let x = 3 // Truthy value.
let y = 0 // Falsy value.
x ||= y

// Log the value of "x":
console.log(x)
// Output:
// 3

// Example 2:
let x = 0 // Falsy value.
let y = 9 // Truthy value.
x ||= y

// Log the value of "x":
console.log(x)
// Output:
// 9

// Example 3:
let x = 3 // Truthy value.
let y = 15 // Truthy value.
x ||= y

// Log the value of "x":
console.log(x)
// Output:
// 3


//
// Nullish coalescing (??):
x ??= y

// Is equivalent to:
x = x ?? y

// Or:
if (x == null || x == undefined) {
    x = y
}

// Example 1:
let x = null // Null value.
let y = 'Hello' // Non-null value.
x ??= y

// Log the value of "x":
console.log(x)
// Output:
// 'Hello'

// Example 2:
let x = 'Jay' // Non-null value.
let y = 'Hello' // Non-null value.
x ??= y

// Log the value of "x":
console.log(x)
// Output:
// 'Jay'

// Example 3:
let x = 'Jay' // Non-null value.
let y = null // Null value.
x ??= y

// Log the value of "x":
console.log(x)
// Output:
// 'Jay'

// Example 4:
let x = undefined // Non-null value.
let y = 'Jock' // Null value.
x ??= y

// Log the value of "x":
console.log(x)
// Output:
// 'Jock'
Enter fullscreen mode Exit fullscreen mode

让我们看一下上面的例子。首先, 。只有当为真时,x &&= y才会赋值y。否则,它会赋值给。其次, 。只有当为假值时,才会赋值给。如果为真且为假,则赋值不会发生。xxyx ||= yyxxxy

x如果和都为假,也会发生同样的情况y。最后一个, 。只有当或 时,x ??= y才会赋值y。如果既不是也不是 ,则赋值不会发生。如果或 ,情况也一样xxnullundefinedxnullundefinedynullundefined

Promise.any()

说到JavaScript 的 Promise,过去一两年可谓是相当火爆。ES6 引入了Promise.race()Promise.all()方法。之后,ES2020 又带来了Promise.allSettled()。ES2021 带来了另一种方法,可以让 Promise 的使用更加便捷,那Promise.any()就是 方法。

Promise.any()方法接受多个 Promise,并在其中任何一个 Promise 实现时返回一个 Promise。第一个实现的 Promise 是 返回的 Promise Promise.any()。如果您提供的所有 Promise 均被拒绝,Promise.any()则将返回AggregateError。其中包含拒绝的原因。

// Example 1: All resolve:
// Create promises:
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise1 is resolved.')
  }, Math.floor(Math.random() * 1000))
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise2 is resolved.')
  }, Math.floor(Math.random() * 1000))
})

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise3 is resolved.')
  }, Math.floor(Math.random() * 1000))
})

;(async function() {
  // Await the result of Promise.any():
  const result = await Promise.any([promise1, promise2, promise3])

  // Log the value returned by Promise.any():
  console.log(result)
  // Output:
  // 'promise1 is resolved.', 'promise2 is resolved.' or 'promise3 is resolved.'
})()


// Example 2: Some resolve:
// Create promises:
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('promise1 is resolved.')
  }, Math.floor(Math.random() * 1000))
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('promise2 was rejected.')
  }, Math.floor(Math.random() * 1000))
})

;(async function() {
  // Await the result of Promise.any():
  const result = await Promise.any([promise1, promise2])

  // Log the value returned by Promise.any():
  console.log(result)
  // Output:
  // 'promise1 is resolved.'
})()


// Example 3: None resolves:
// Create promises:
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('promise1 was rejected.')
  }, Math.floor(Math.random() * 1000))
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('promise2 was rejected.')
  }, Math.floor(Math.random() * 1000))
})

;(async function() {
  // Use try...catch to catch the AggregateError:
  try {
    // Await the result of Promise.any():
    const result = await Promise.any([promise1, promise2])
  }

  catch (err) {
    console.log(err.errors)
    // Output:
    // [ 'promise1 was rejected.', 'promise2 was rejected.' ]
  }
})()
Enter fullscreen mode Exit fullscreen mode

弱引用

ES2021 的最后一个显著特性是WeakRefs。在 JavaScript 中,当你创建对某个对象的引用时,它会阻止该对象被Garage Collection回收。这意味着 JavaScript 无法移除该对象并释放其内存。只要存在对它的引用,对象就可能永远存在。

ES2021 引入了新的 class WeakRefs。这将允许开发者创建对对象的弱引用。借助它,开发者可以跟踪现有对象,而不会阻止它们被垃圾回收。这对于缓存和对象映射非常有用。

当你想要创建新对象时WeakRef,必须使用new关键字 new 。你需要将某个对象作为参数传入括号中。当你想要读取引用(被引用的对象)时,可以通过调用deref()弱引用来实现。我们来看一个非常简单的例子。

const myWeakRef = new WeakRef({
  name: 'Cache',
  size: 'unlimited'
})

// Log the value of "myWeakRef":
console.log(myWeakRef.deref())
// Output:
// { name: 'Cache', size: 'unlimited' }

// Log the value of "name" property:
console.log(myWeakRef.deref().name)
// Output:
// 'Cache'

// Log the value of "size" property:
console.log(myWeakRef.deref().size)
// Output:
// 'unlimited'
Enter fullscreen mode Exit fullscreen mode

Finalizers 和 FinalizationRegistry

与 紧密相关的是WeakRef,ES2021 还有另一个称为 终结器 (或 )的功能FinalizationRegistry。此功能允许您注册将在对象被垃圾回收时调用的回调函数。

// Create new FinalizationRegistry:
const reg = new FinalizationRegistry((val) => {
  // Print the value of "val" when invoked:
  console.log(val)
})

;(() => {
  // Create new object:
  const obj = {}

  // Register finalizer for the "obj" obj:
  // 1st argument: object to register finalizer for.
  // 2nd argument: value for callback function defined above.
  reg.register(obj, 'obj has been garbage-collected.')
})()
// Output when "obj" is garbage-collected:
// 'obj has been garbage-collected.'
Enter fullscreen mode Exit fullscreen mode

关于 finalizer 和 finalizer 有一点很重要WeakRef。该特性的提案本身建议不要使用它们。原因之一是它们可能不可预测。另一个原因是它们实际上并没有帮助垃圾收集器完成其工作。它们实际上会使垃圾收集器的工作更加困难。您可以在提案中阅读更多关于原因的内容。

结论:值得关注的 JavaScript ES2021(ES12)新功能

与之前的 JavaScript 规范(例如 ES6 和 ES2020)相比,ES2021(ES12)可能显得微不足道。然而,它有一些值得关注的有趣特性。希望本教程能帮助您了解这五个实用特性,让您的工作更轻松。

鏂囩珷鏉ユ簮锛�https://dev.to/alexdevero/upcoming-interesting-javascript-es2021-es12-features-to-look-for-1oe8
PREV
JavaScript 中的 WeakMap - 简单介绍
NEXT
如何通过三种方式编写异步 JavaScript 代码