这篇文章的框架主要以 TC39 proposals 中 2020 年的 finished-proposals 来进行编写,并以 MDN 的资料来进行辅助了解。

image.png

String.prototype.matchAll()

这个方法与正则表达式相关,该方法返回一个迭代器,这个迭代器包含了字符串中所有匹配的结果。由于返回的结果是迭代器,因此可以对结果使用 for...of 、扩展运算符以及 Array.from()

需要注意的是,使用 String.prototype.matchAll() 时,正则表达式必须带上 g 标志,否则会报错。

  1. const regexp = /t(e)(st(\d?))/g;
  2. const str = 'test1test2';
  3. const array = [...str.matchAll(regexp)];
  4. console.log(array)
  5. // Array [Array ["test1", "e", "st1", "1"], Array ["test2", "e", "st2", "2"]]

如果使用 RegExp.prototype.exec() 来实现相同功能,则会繁琐一些:

  1. const regexp = /t(e)(st(\d?))/g;
  2. const str = 'test1test2';
  3. let result
  4. while((result = regexp.exec(str)) !== null) {
  5. console.log(result)
  6. }

所以我们可以将 String.prototype.matchAll() 看做 RegExp.prototype.exec() 匹配字符串的便捷版。

推荐阅读

Dynamic Import(动态加载)

Dynamic import 可以在 js 中动态加载一个模块。这个特性可以帮助我们实现按需加载,也就是我们所熟知的 code splitting。

Dynamic import 的语法是 import(module) ,它返回一个 promise 对象,它的 resolve 参数为一个包含了模块所有导出的对象。

  1. // foo.js
  2. export const a = 'a'
  3. export const b = 'b'
  4. export default 'c'
  1. // bar.js
  2. let foo = await import('./foo.js');
  3. console.log(foo) // { a: 'a', b: 'b', default: 'c' }

上面的例子中,bar.js 通过 dynamic import 加载 foo.js,可以看出 foo 变量包含了 foo.js 中所有的导出。

推荐阅读

BigInt

BigInt 对象是用于表示大于 ES2020 (ES11) - 图2 的数,这个是 Number 类型所能表示的最大的整数。除了使用 BigInt 来创建大树,还可以通过整数+ n 的形式,如 10n

  1. BigInt(9007199254740991)

需要注意的是 BigInt(0) !== 0 ,因为 BigInt 创建的数值跟 Number 类型数值并不是同一样东西。

推荐阅读

Promise.allSettled()

Promise.allSettled 接收一组 Promise,并返回一个新的 Promise 对象。当所有的 Promise 状态为 resolved 或者 rejected 状态的时候,新的 Promise 对象将变为 resolved 状态,它的结果为所传入的那一组 Promise 对应的结果。

  1. const promise1 = Promise.resolve(3);
  2. const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
  3. const promises = [promise1, promise2];
  4. Promise.allSettled(promises).
  5. then((results) => results.forEach((result) => console.log(result.status)));
  6. // expected output:
  7. // "fulfilled"
  8. // "rejected"

推荐阅读

globalThis

globalThis 包含全局 this 值,类似于全局对象。在 globalThis 之前,不同的 JavaScript 环境获取全局对象使用使用不同的语句,例如在浏览器中使用 window 获取全局对象,而在 Node 环境中则是通过 global 来获取全局对象。而 globalThis 则提供了一个标准的方式来获取不同环境下的全局对象。

下面这段代码,在浏览器环境以及 Node 环境中通过 globalThis 来获取全局变量中的 setTimeout 方法。

  1. globalThis.setTimeout(() => {
  2. globalThis.console.log('hello')
  3. })

推荐阅读

for-in mechanics

这个特性指定了 for-in 枚举的顺序。提案中提到了指定 for-in 枚举顺序的原因:

ECMA-262 leaves the order of for (a in b) … almost totally unspecified, but real engines tend to be consistent in at least some cases. Furthermore, over the years implementations have observed that anyone who wants to run code on the web needs to follow some constraints not captured by the spec.

This is a stage 4 (finished) proposal to begin fixing that.

Historical efforts to get consensus on a complete specification of the order of for-in have repeatedly failed, in part because all engines have their own idiosyncratic implementations which are the result of a great deal of work and which they don’t really want to revisit.

推荐阅读

Optional Chaining (?.)(可选链操作符)

当对象有比较深的层次的时候,通过 ?. 操作符可避免繁重的 nullish 值校验。例如:

  1. // 使用 ?. 运算符之前
  2. let nestedProp = obj.first && obj.first.second && obj.first.second.third;
  3. // 使用 ?. 运算符
  4. let nestedProp = obj.first?.second?.third;

在使用 ?. 操作符时,如果某个环节出现 nullish 值( null 或者 undefined )的情况,那么将返回 undefined 值。

  1. const obj = {
  2. foo: 'foo'
  3. }
  4. console.log(obj.foo?.bar?.name) // undefined

推荐阅读

Nullish Coalescing (??)(空值合并)

Nullish coalescing 运算符 ( ?? ) 会在左侧操作数为 null 或者 undefined 的时候返回右侧操作数,否则返回左侧操作数。

??|| 非常类似, ?? 看左侧操作数是否为一个 nullish 值,而 || 看左侧操作数是否为一个 falsy 值。

  1. let myText = ''
  2. console.log(myText ?? 'Hello world') // ''
  3. console.log(myText || 'Hello world') // 'Hello world'

推荐阅读

import.meta

import.meta 包含了模块的信息,如模块的 URL。类似于 CommonJS 中提供的 __dirname__filename

参考资料