[译]ES2020中新增的功能

咱们最喜欢的编程语言JavaScript的第11版规范草案ECMAScript2020中包含了不少新功能。其中一些是小的特性,也有一些特性拥有永久改变咱们编写JavaScript方式的潜力。前端

本文是对这些新功能的简短概述,沏好茶,让咱们一块儿开始吧~web

动态引入,import()

ES2015中提到到了static import语法,即普通的引用语法。让你能够从一个模块导出一个变量,而后,直接在另一个模块中引用。编程

下面的代码为静态引用的例子:数组

// utils.js
export function splitName(name{
  return name.split(" ");
}

// index.js
import { splitName } from "./utils";

console.log(splitName("John Snow"));
复制代码

这种语法被称为静态引用,是由于你没有办法在运行时经过某种条件来动态的引用某一个模块。可是请注意,这不必定是坏事,静态引用容许你在编译时经过Tree Shaking来优化代码(动态的引入使用到的代码,减小打包的bundle包大小)。promise

另外一方面,若是可以合理的利用动态引用,也能够经过按需加载依赖包的方式,减小bundle包的大小。浏览器

新的动态引用的语法看起来像一个函数(可是,他并非函数),它返回一个promise,这意味着咱们可使用async/await。来看个例子机器学习

// 根据条件动态选择须要加载的模块
const mod = figure.kind === "rectangle" ? "rectangle.js" : "circle.js";
// 等待模块加载完成
const { calcSquare } = await import(mod);
console.log(calcSquare(figure));
复制代码

空位合并,新运算符 ??

经过||运算符来设置一个值的默认值有它的缺陷。由于它并非真正的检查值是否为,它仅仅是检查这个值是否为。当一个值为false或者0时,这个设置默认值的方法就会出问题。async

ES2020提供了一种新的运算符??,它和||的工做原理很相似,可是,它仅仅在初始值为null或者undefined时才会取右侧的值。编程语言

这里有一个简单的示例:编辑器

const initialVal = 0;

// old way
const myVar = initialVal || 10// => 10

// new way
const myVar = initialVal ?? 10// => 0
复制代码

可选链,Optional chaining

可选链操做符?.设计的目的是为了让咱们在检查多层嵌套的对象的某个属性是否存在时,不须要去写冗长的代码。

const user = { name"John" };

// 这里会报错 `Uncaught TypeError: Cannot read property 'city' of undefined`
const city = user.address.city;

// 可执行,可是,代码冗长
let city = "Not Set";
if (user.address !== undefined && user.address !== null) {
  city = user.address.city;
}

// 可执行而且简洁,可是,须要第三方库的支持
const city = _.get(user, "address.city""Not Set");

// 🤗
const city = user?.address?.city ?? "Not Set";
复制代码

译者注:这个功能真的不错,不再须要写一大堆&&判断啦。。

BigInt

BigInt是一个新的对象,用来表示大于Number.MAX_SAFE_INTEGER(2^53-1)的数字。对于普通的应用来讲,原来的数字听起来就足够使用了,可是,对于某些数学应用或者机器学习来讲,BigInt就须要派上用场啦。

经过在数字后面增长一个字母n,便可将一个数字指定为BigInt

const x = 9007199254740991n;

// 或者你也能够经过给构造函数传一个字符串来实现
const y = BigInt("9007199254740991234");
复制代码

BigInt和普通数字并不能互相转化,所以咱们不能混合使用两者。要想使用须要先将2个数强制统一成一个类型。

1 === 1n; // => false
1n + 1// throws Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
6n << 3// throws Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
6n << 3n; // 48n
复制代码

String.matchAll

这里有一个例子,想象一下你有一个很长的字符串,而且你须要提取出来全部以#开头的词。

const tweet = "#JavaScript is full of #surprises. Both good and bad ones #TIL";

for (h of tweet.matchAll(/(#\w+)/g)) {
  console.log(h[0]);
}

// or

const tags = [...tweet.matchAll(/(#\w+)/g)]
复制代码

译者注:额,string.match也能实现上述功能

matchAll返回的是一个迭代器,能够经过for..of来循环它,也能够将它转换成一个数组。

Promise.allSettled

还记得Promise.all函数么?当全部promise都触发了resolve状态,它才会进入resolve状态。可是,当其中一个promise进入了reject状态,整个Promise.all就会直接进入reject状态,不管其余promise是否还处在pending状态。

Promise.allSettled的表现和Promise.all不同。当全部promise完成工做了,它会进入resolve状态,不管,这些promise是进入了resolve或者reject。它会将全部promise的处理结果都经过resolve函数返回出来。

所以,allSettled没有reject状态,他只有pendingresolve状态。

下面是一个是现实世界的问题:去除loading框

// const urls = [...]
try {
  await Promise.all(urls.map(fetch))
catch (e) {
  // 至少有一个promise进入了reject状态,可是,其余promise可能还处在pending中,这样会致使loading去除的过早
  removeLoading()
}

// 使用allSettled
await Promise.allSettled(urls.map(fetch))
removeLoading()
复制代码

globalThis

在JavaScript中,有一个包含任何东西的巨大上下文。通常来讲,在浏览器中它是window对象。在Node应用它又变成了global对象。到了webWorker中,它又变成了self对象。

新的globalThis属性消除了环境带来的差别性,你可使用globalThis引入而不须要关心你所处的上下文。

若是你认为这个命名有点尴尬,我彻底赞成您的意见,可是请注意,以selfglobal命名可能会不兼容某些较旧的代码。因此我想咱们必须忍受这一点。

关于译者本人

我是一个莫得感情的代码搬运工,如今主要精力会投在更新《Laya2.x游戏引擎入门系列》上,由于实在拖的过久啦,对不住本身年前定的计划。

最近,搞了一个公众号,你们有兴趣的话关注一下,咱们一块儿交流前端知识~

好啦,翻译完毕啦,原文连接在此 What's new in ECMAScript 2020

相关文章
相关标签/搜索