E

ECMAScript 2019 及后续... ECMAScript 2019 发布周期 未来会怎样? 想了解更多?

2025-06-04

ECMAScript 2019 及更高版本...

发布周期

ECMAScript 2019

未来会怎样?

想要了解更多?

这篇文章取自我的博客,因此请务必查看以获取更多最新内容。

上个月——2019 年 6 月——ECMA-262 标准第十版正式发布。这意味着什么?—— ECMAScript 2019来了!这是 JavaScript 及其他衍生语言即将遵循的最新、最强大的规范。虽然您可能已经听说过它的一些新功能,但我们会一一回顾!此外,还会介绍一些 ECMAScript 的细节,并预告未来的发展!

发布周期

虽然我们已经知道ECMAScript 是什么,以及它现在每年的发布周期是如何运作的,但它还有一些更有趣的事情。

当然,每个新的 ES 规范的发布都很重要,但建议不要将其视为一年一次的事情(除非您生活在 ES6 之前的时代)。该规范是“活的”,在您阅读本文时仍在不断完善。每个版本都只是一系列新功能的总结。您应该这样看待它——逐个功能地进行。

您现在可能已经知道(可能是因为之前使用过 Babel),ECMAScript 规范是基于不同的提案而创建的。每个提案都需要经历 5 个不同的阶段……

每个新提案最初都只是一个想法,需要先经过TC39的审核。该委员会由来自不同公司/组织(例如 Google 和 Mozilla)的专家和代表组成,负责决定规范的未来发展方向。提交的想法获得积极评价后,将进入stage-0 阶段。从现在开始,它将公开发布,并可从相应的GitHub 代码库中获取。随着提案在TC39 例会上得到进一步讨论,它要么进入下一阶段,要么被放弃。处于stage-3 阶段的提案通常被认为非常稳定且有保障。提案到达stage-4 阶段后即成为正式提案。

现在,所有这些过程——不同的阶段等等——并不一定与实现时间相匹配。许多浏览器厂商为了让自己的浏览器保持活力并吸引开发者,经常会在阶段 3 时就实现这些功能。当然,由于这些功能仍然不是标准,很多人很可能会使用Babel,或者根本不会使用它们!但这仍然是事实。话虽如此,有些功能甚至可能在官方规范发布一段时间后才会实现。但是,自从 ES6 的上一个“重大”版本发布以来,这种情况并不常见。

ECMAScript 2019

ES 发布周期已经结束,让我们来探索一下 ES2019 的所有新功能吧!我知道你可能之前已经看过这些了,但请耐心等待,我们将再次以一种更适合初学者的方式进行探索!

Array.prototype.flat{Map}()

正如我之前提到的,ES2019 的许多特性在官方规范发布之前就能在浏览器中实现。例如,两个新的不可变数方法.flat().flatMap()

我已经介绍过这些方法了如果你想了解更多,可以去看看。这里稍微复习一下!

const arr = [1, [2, [3, 4]]];

arr.flat(2); // [1, 2, 3, 4]
arr.flatMap(num => `${num}`); // ["1", "2,3,4"]
Enter fullscreen mode Exit fullscreen mode

我认为这些方法的命名已经揭示了它们的全部功能。.flat()可以用来展平多维数组。默认情况下,它的深度为 1 层,但你可以选择传递一个参数来指定深度,就像我们在上面的例子中所做的那样。

因为.flat()与 结合使用.map()会非常有用,所以还有一个特殊的方法!- .flatMap()。这个方法首先映射数组,然后将其展平为 1 层深度(这里无需配置)。当然,所有这些都带来了性能的提升!

对象.fromEntries()

ES6引入了Map对象,并且需要以键值对的形式用数组表示数据,因此Object.fromEntries()在执行此类操作时非常有用。它可以将包含键值对(条目)的数组或 Map 转换为实际的对象——而在 ES2019 之前,这需要自定义代码。

const arr = [
    ["key1", "value1"],
    ["key2", 2],
    ["key3", {value: 3}]
];

Object.fromEntries(arr); 
// { key1: "value1", key2: 2, key3: { value: 3 } }
Enter fullscreen mode Exit fullscreen mode

String.prototype.trimStart() 以及更多...

ES5.trim()方法新增了 2 个方法,甚至 4 个!之前.trim()我们一直在尝试从字符串两侧移除不必要的空格,现在新增了一些方法,只需从指定的字符串中移除即可!

.trimStart(),也称为.trimLeft(),可用于从字符串的起始/左侧修剪字符串...

const str = "     str     ";

str.trimStart(); // "str     "
str.trimLeft(); // "str     "
Enter fullscreen mode Exit fullscreen mode

.trimEnd().trimRight()可以用来做同样的事情,从右侧开始。

const str = "     str     ";

str.trimEnd(); // "     str"
str.trimRight(); // "     str"
Enter fullscreen mode Exit fullscreen mode

可选的 catch 绑定

ES2019 除了带来一些新方法外,还修复了前代版本的一些缺陷。首先,即使不使用错误参数,也要求在try/语句中包含它。catch

// then
try {
    // ...
} catch(error) {
    // ...
}

// now
try {
    // ...
} catch {
    // ...
}
Enter fullscreen mode Exit fullscreen mode

编写的代码越少越好,对吗?

函数.prototype.toString();

在基于 ES 的语言中,.toString()几乎所有事情都可以做到!不同的调用最终会解析成什么又是另一回事。但是,在 ES2019 之前,当与函数一起使用时,它.toString()只会返回一个包含函数代码的字符串。现在,它还会考虑注释、换行符和空格——所有的一切!

function toBeStringified() {
    // a comment

    // a comment after new line
}

toBeStringified.toString();
/*
`function toBeStringified() {
    // a comment

    // a comment after new line
}`
*/
Enter fullscreen mode Exit fullscreen mode

符号.原型.描述

Symbol- 始终唯一的数据类型,主要用作对象的属性标识符 - 刚刚添加了一个名为 的新属性.description。它可用于Symbol以字符串形式访问 的可选传递的描述参数。

const mySymbol = Symbol(2);

mySymbol.toString(); // "Symbol(2)"
mySymbol.description; // "2"
Enter fullscreen mode Exit fullscreen mode

数组.prototype.sort()

如果您以前使用过.sort(),您可能知道建议不要依赖其默认排序算法。这是因为在之前的规范中没有提到该算法的任何稳定性要求。现在,在 ES2019 中,规范要求使用“稳定排序”,每个 JS 引擎都需要遵循它。这意味着它们仍然可以使用不同的算法,但不应该有任何与此相关的误解。要了解我的意思,请查看下面的示例。

const dogs = [
  { name: "Abby",   rating: 12 },
  { name: "Bandit", rating: 13 },
  { name: "Choco",  rating: 14 },
  { name: "Daisy",  rating: 12 },
  { name: "Elmo",   rating: 12 },
  { name: "Falco",  rating: 13 },
  { name: "Ghost",  rating: 14 },
];

// Sort the dogs by `rating` in descending order.
dogs.sort((a, b) => b.rating - a.rating);
/* 
[
  { name: "Choco",  rating: 14 },
  { name: "Ghost",  rating: 14 },
  { name: "Bandit", rating: 13 },
  { name: "Falco",  rating: 13 },
  { name: "Abby",   rating: 12 },
  { name: "Daisy",  rating: 12 },
  { name: "Elmo",   rating: 12 },
]
*/
Enter fullscreen mode Exit fullscreen mode

正如您在上面的结果注释中看到的,数组按照我们的排序函数“预期”排序。在原始版本中,项目按字段的字母顺序排序name。现在,它们按ratingfirst 排序,但仍然按字母顺序排列。第二个事实在某种程度上是预期的(排序后的项目应该保留其先前的位置),但在 ES2019 之前,这并不能保证。从现在开始,新浏览器将保证正确的顺序。但请注意,旧浏览器仍然存在。这就是为什么您在编写排序函数时应该非常明确,而不必过分依赖浏览器的默认行为。

关于 JSON 的一句话...

JSON 和 JSON 相关功能也得到了一些修改!

JSON.stringify()现在可以正确地转义 Unicode 的“单独代理”。考虑到你可能很少遇到与此相关的问题,这不算什么大问题。不过,在编写代码时,这还是值得少考虑的。举个例子:

// then
JSON.stringify('\uD800'); // "'�'"

// now
JSON.stringify('\uD800'); // "'\\ud800'"
Enter fullscreen mode Exit fullscreen mode

ES2019 修复了 Unicode 字符串的另一个问题!JSON 通常被认为是 ECMAScript 的子集,但在此之前并非完全如此。JSON 字符串可能包含一些未转义的 Unicode 字符(U+2028U+2029),而 ES 字符串则不能。现在,ES 支持这些字符,问题已得到解决,JSON 真正成为了 ES 的子集。

未来会怎样?

既然我们已经介绍了 ES2019 的所有优点,接下来是什么呢?即使还处于 Stage-3,现代浏览器引擎(例如 V8)也不断推出新功能!其中一些已经计划在ES2020中推出,而其他一些则没有。但是,我想让你稍微预览一下未来,在某些情况下,现在就可以体验到!话虽如此,以下是 ES2020 及以后最值得期待的 3 个功能!

动态导入()

据我所知,即使 ES 模块已获得所有主流浏览器的官方支持,许多开发者仍然在使用代码打包工具。但谁又能责怪他们呢?模块确实需要更多“标准化” ——不是来自规范,而是来自社区。为此,需要一些时间,旧的浏览器必须淘汰……

但是,所谓的动态import()肯定会成为“模块化未来”的一部分。好吧……也许“未来”这个词有点太大胆了,考虑到这个功能已经被所有主流浏览器支持,并且处于stage-4 阶段,计划在ES2020中实现。

import("module.mjs")
    .then((module) => {
      module.default(); // export default stuff
      module.doStuff(); // other stuff
    });
Enter fullscreen mode Exit fullscreen mode

动态模块的主要优势import()在于它以惰性加载的方式加载模块。通过这种方式,你可以显著提升应用的性能,只需先加载必要的内容(使用标准语句),然后再加载其他内容即可。此外,使用/ !import加载时,这些加载在语法上几乎难以察觉。asyncawait

(async () => {
    const module = await import("module.mjs")
    module.default();
    module.doStuff();
})();
Enter fullscreen mode Exit fullscreen mode

BigInt

在 JS 中处理大数字可能相当棘手。可能值的范围很大,但在某些情况下,这些值仍然不够用。这就是它BigInt诞生的原因!

BigInt是一个全新的数字原语,与当前可用的 兼容Number。它已经在基于 Chromium 的浏览器和其他一些浏览器中实现BigInt,但仅此而已。一旦超越 stage-3 并似乎在 ES2020 中正式发布,对它的支持肯定会进一步增强。

目前,在支持变得更好之前,我认为您需要知道的是,您将能够以出色的性能在 JS 中表达一些大数字,而无需任何第三方库!

BigInt(Number.MAX_SAFE_INTEGER) + 2n; // 9007199254740993n
/* Value bigger than Number can represent
   BigInts can be created with -n suffix */
Enter fullscreen mode Exit fullscreen mode

当然,顾名思义,BigInt它只能用来表示整数。这让我非常期待未来可能出现的BigDecimal (或者类似的东西)……

私有类字段

这可能是 ES 最令人期待的功能之一。私有类字段是许多开发者梦寐以求的。它能够真正隐藏实现细节!

私有类字段目前处于第三阶段。目前尚不确定我们是否会在 ES2020 中看到它们。尽管这个功能可能很棒,我仍然对它有一些担忧。首先,目前的提案中没有提到任何类型的受保护字段——使用 TypeScript 或其他静态类型语言的人都知道我在说什么。而且,更糟糕的是——ES 提案中私有字段的语法……在我看来很糟糕。 和 关键字的跨语言标准井号 ( ) 符号取代了。即便如此,我仍然很高兴这样的功能(无论以何种形式)即将出现在 JS 中!publicprotectedprivate#

class IncreasingCounter {
    #count = 0;
    get value() {
        console.log("Getting the current value!");
        return this.#count;
    }
    increment() {
        this.#count++;
    }
}
Enter fullscreen mode Exit fullscreen mode

想要了解更多?

ES 规范和提案每天都在更新。浏览器和 JS 引擎也一样。如果您想了解最新、最强大的功能,我建议您查看v8.dev博客,V8背后的团队会在那里分享关于引擎、其最新功能及其实现方式的深刻见解。强烈推荐!

好了,本文就到这里。欢迎关注我的TwitterFacebook主页,或者访问我的个人博客,获取更多精彩内容。祝您拥有美好的一天!

文章来源:https://dev.to/areknawo/ecmascript-2019-and-beyond-12c6
PREV
使用控制台 API 发挥创意!Console.log() 分组与追踪 Console.XXX 计时计数表 Console ASCII 艺术 现代日志
NEXT
DOM 性能案例研究 重排 批处理 杂项 从不同角度谈虚拟 DOM 底线 资源