25

Ecma International 负责对 JavaScript 标准化。是他们制定了 ECMAScript 规范。当提到 ECMAScript 时,基本上可以把它看作是 JavaScript 的同义词。从 2015 年开始,开始用年份标记版本,即 ECMAScript 2015 缩写为 ES2015。但是也会使用版本号的计数,所以 ES6 与 ES2015 相同。尚未发布的功能被称为 ESNext。

ECMAScript 2020/ES2020/ES11 于 6 月发布,并且已经在现代浏览器中实现。让我们看看这会带来什么好处。

太长不看版

如果你不想看细节,那么只看这张图就够了。

image.png

空值合并

如果你在赋值时想要一个默认值(如果它为 nullundefined ),则可以使用 ??

const name = person.fullName ?? 'anonymous';

如果对象 person 没有 fullName 值,则 name 将被赋值为 “anonymous”。如果 person 的 fullName 有值,则把该值赋值给变量 name

你可能认为用 || 就能做到。但这几乎是几乎相同的,如果 || 前面的值是虚值,那么这个表达式将不会短路,并且会使用后面的值。但是请记住,空字符串 ''0NaNfalse 都是虚值,在这些情况下将使用默认值,如果我们要用这些进行赋值的话,就行不通了。 ?? 则只检查 nullundefined

const user = { preferredSound: 0 }
let sound = user.preferredSound ?? 50 // value is 0
let soundWrong = user.preferredSound || 50 // value is 50

仅当 preferredSoundundefined 或者 null 时才使用 50 这个值。

可选链

如果要使用多级嵌套在对象中的属性,在以前必须要检查它们是否为 nullundefined,以避免代码崩溃。现在可以在访问这些属性之前使用 ?.,这样就可以只有在值不为 nullundefined 时使用 ?. 后面的代码。

例如:

const house = { owner: { name: 'Jim', pet: null }};// Old JavaScript
if(house && house.owner && house.owner.pet && house.owner.pet.type === 'dog'){
  console.log('owner has a dog');
}// ES2020
if (house?.owner?.pet?.type === 'dog') {
  console.log('owner has a dog');
}

Promise.allSettled

如果要执行更多的异步请求,可以使用 Promise.all 来收集它们。但是如果其中任何一个请求失败的话,将会引发异常。如果我们希望每个请求都能够完成,无论其请求是否失败,那该怎么办。这时可以用 Promise.allSettled,当所有请求都被解决或拒绝时,它将返回。

const promises = [Promise.resolve(1), Promise.reject(2)];
const [result1, result2] = await Promise.allSettled(promises);

即使其他 promise 被拒绝了,我们仍然可以在这里使用 result1 的值。

matchAll

如果要用正则表达式查找所有的匹配项,可以用 match 来得到所有子字符串。但是,如果你既需要子字符串又需要索引,该怎么办?这时可以用 matchAll 并进行重复匹配。

例如找到一个字符串中的所有数字:

const matches = 'Here are some numbers: 5 12 88'.matchAll(/\d+/g);
for (const match of matches) {
  console.log(match);
}// 输出:
// ["5", index: 22, input: "Here are some numbers: 5 12 88", groups: undefined]
// ["12", index: 24, input: "Here are some numbers: 5 12 88", groups: undefined]
// ["88", index: 27, input: "Here are some numbers: 5 12 88", groups: undefined]

BigInt

BigInt 是 JavaScript 中新的原始数据类型,与 BooleanNumberStringSymbolundefined 的地位相同。 BigInt 可以安全的处理大于 Number 限制的整数数字。也就是说如果要处理大于 9007199254740991 的数字时应该用 BigIntBigInt 在数字末尾用 n 表示。

9_007_199_254_740_991 + 2; // 9007199254740992
BigInt(9_007_199_254_740_991) + BigInt(2) // 9007199254740993n

动态导入

以前只能在文件开头静态导入模块。现在有了动态导入,可以按需在代码中的任何位置进行这种操作。import() 会与模块一起返回一个 Promise。

const module = await import('module');

模块命名空间导出

在大多数情况下,我们能够通过导入导出 JavaScript 模块来重命名模块的名称,就像这样:

import * as values from 'module';
import { value as v } from 'module';export { v as value };

但是没有办法直接从名称被更改的另一个模块中重新导出某些内容。现在有了 ES2020,则可以这样做:

export * as someUtils from 'utils';

globalThis

如果你的代码需要在多个环境(例如浏览器和 Node 服务器)下运行,那么它们所使用全局对象名称并不一致。在浏览器中用的是 window,Node 则用的是 global,而 web worker 用的是self。现在,无论代码在哪种环境中运行,globalThis 都能够为你提供正确的全局对象。

下面是一个例子,我们需要检查是否可以向用户提示 alert。如果代码在浏览器中运行,则 globalThis 将会引用 window,并且 alert 也可以使用。

if (typeof globalThis.alert === 'function'){
  globalThis.alert('hi');
}

173382ede7319973.gif


本文首发微信公众号:前端先锋

欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章

欢迎扫描二维码关注公众号,每天都给你推送新鲜的前端技术文章


欢迎继续阅读本专栏其它高赞文章:



疯狂的技术宅
44.4k 声望39.2k 粉丝