ECMAScript 2021主要新功能 – thenewstack


ECMAScript 的下一个年度更新(JavaScript 语言的正式规范)将于今年 7 月发布,今年对 JavaScript 的添加主要是着重改进方面,让开发人员更愉快地使用该语言,提供新功能或更简单的方式来表达可以用其他方式完成的事情。但是有一个强大的新选项也是对语言的一个相当根本的改变,它专门用于支持 WebAssembly。
 
Promise.any
使用Promise.any,JavaScript 现在有四种方法来处理异步操作集来处理 promise 的解决方式(通过实现或拒绝):

  • Race 允许您跟踪多个promise 并在第一个承诺成功或失败时立即采取行动。
  • 只有当所有的promise 都成功时,才成功。
  • allSettled 返回一个数组,列出每个promise 是成功还是失败。
  • any 会在任何promise 成功时立即成功来填补空白,如果它们都失败则失败。

当您遇到提供一些冗余的情况时,Promise.any 最有用。想象一下,您可以从多个不同的网站获取文档或资源。也许您希望通过并行地从多个不同的服务器请求它来加速您的网站的性能,而您并不关心这些请求中的哪一个成功。你感兴趣的只是第一个成功完成后的结果。
Promise.any 不会自动终止任何其他请求;在 Promise.any 返回结果后,您仍然需要手动取消它们。
如果所有的 Promise 都被拒绝, Promise.any 会返回一个聚合错误:来自每个 Promise 的单个错误的数组,因为您可能需要准确地知道每个操作失败的原因。
Promise.allSettled 向 JavaScript 引入了聚合错误。Promise.any对聚合错误进行了标准化,以确保任何未来的功能都将使用相同的语法——因为它是一种非常有用的错误类型,已经广泛用于库(以及他工作的 Azure SDK)中。ECMAScript 的未来版本可能包括向 Error 构造函数添加原因,链接一系列错误,以便您可以跟踪它们来处理底层问题,这将与聚合错误一起工作。
 
String.prototype.replaceAll
字符串的新替换函数修复了 JavaScript 中另一个长期存在的漏洞。
以前,除非您使用 /G 标志并编写全局正则表达式来替换所有实例,否则替换只会更改字符串的第一个实例。StackOverflow 上很多开发人员正在寻找有关如何处理此问题的信息,这是一个常见的绊脚石。
很多人可能只是没有意识到这一点,并使用replace来实现替换功能,以为它将替换所有实例,然后没有。现在那些不喜欢正则表达式的人终于可以有了他们一直想要的替换功能了。
 
逻辑赋值运算符
JavaScript 已经允许您通过组合数学运算符来编写更简洁的代码;x += y 而不是 x = x + y。
使用Logical assignment,开发人员将能够使用 &&、或 || 等逻辑运算符执行类似数学运算一样的操作: x ||= y 而不是 x ||(x = y)。
这是一种非常常见的语法糖,它避免了有人向你传递一个但有效的值,如 false、0 或空字符串,但你最终会用默认值覆盖它。
 
数字分隔符
当一个长数字被拆分成逻辑块时,确保正确读取它要容易得多。由于在 ECMAScript 2020 中引入了 BigInt,开发人员现在可以处理非常大的整数。数字分隔符是一种语法糖,通过用下划线将它们分开,使这些长数字更易于阅读,因此您可以输入 1_000_000_000 而不是 1000000000 来表示 1,000,000,000。
下划线已经在 J​​ava、Python、Perl、Ruby、Rust、Julia、Ada 和 C# 中以这种方式使用。这些下划线没有语义;他们纯粹是为了让我们的数字变得美丽。
 
Intl.DisplayNames
每个站点是否都需要自己的货币、语言或地区名称的翻译列表,以便在语言、地区和脚本选择器的下拉菜单中使用?Intl.DisplayNames为一些常用(和翻译)字符串提供标准翻译,例如语言名称和星期几。
在某些时候,您将需要一个下拉菜单供用户选择语言,如果能够做到这一点,而无需为每种语言手动创建翻译,那就太好了,因为我们有数据库具有本地语言本地名称的计算机。
如果开发人员不需要包含人类可读的语言、区域和脚本显示名称形式,他们可以编写更短、更易读的 HTML 和 JavaScript。浏览器每次下载的内容都会减少,如果开发人员不编写或复制粘贴该代码(或编写代码来解析 Intl.DateTimeFormat 的输出),他们就不会在其中犯错。这使得本地化变得更容易、更便宜。
 
WeakRef 和 FinalizationRegistry
JavaScript 的一大优势是开发人员通常不需要进行手动内存管理,因此垃圾收集在各个浏览器和其他 JavaScript 引擎之间可能有所不同但不重要。通常,对象的引用可在 JavaScript 中被强保留:只要您有对对象的引用,它就不会被垃圾收集。
如果您想通过删除不再需要存储的数据来节省内存,则必须明确删除强引用,例如事件侦听器。即使现有的 WeakMap 和 WeakSet 构造也不是真正的弱引用:新的 WeakRef 是一个真正的弱引用,您可以使用它来包装事件侦听器之类的东西,因此它们可以被垃圾收集。
这是 JavaScript 中的一项基本新功能,在哲学上与通常的方法非常不同。
当您确实需要使用事件侦听器或通过在线性缓冲区中分配内存来进行手动内存跟踪时,JavaScript 没有很好的构造来处理它。怎么把这自动和手动处理内存的两个世界结合起来?
WeakRef 解决了这个问题,尽管代价是额外的工作,无论何时你想使用对象,也许是取消引用它,你必须问它,'你还在吗?' 如果其他人都发布了对它的强引用,您可能会发现它不再存在。
这也有助于处理订阅等相关资源;让订阅回调使用弱引用来轮询对象意味着当不再需要主对象时,订阅不会意外地使主对象保持活动状态。
缺点:弱引用可能意味着开发人员正在编写不再可移植的代码。
那么为什么要引入一个被 ECMAScript 6 考虑并拒绝并且可能永远不会被绝大多数 JavaScript 开发人员使用的潜在危险特性呢?因为它改进了与 WebAssembly 的集成——在 JavaScript 引擎中实现的日益流行的内存安全、沙盒、执行环境。
  
符合人体工程学的Finalizers
Finalizer用途:程序员可以注册回调,这样能在对象被垃圾回收时接收事件,而不是轮询对象,这样他们就可以删除支持它的资源。
为了避免出现问题,他建议不要在Finalizer终结器后面控制重要的行为;根据 JavaScript 引擎,垃圾收集运行时可能不会立即调用Finalizer终结器,它们可能不会按顺序调用,并且在某些情况下——比如在高性能情况下运行的紧密循环——它们可能根本不会被调用。