[譯]ES2020中新增的功能

咱們最喜歡的編程語言JavaScript的第11版規範草案ECMAScript2020中包含了不少新功能。其中一些是小的特性,也有一些特性擁有永久改變咱們編寫JavaScript方式的潛力。javascript

本文是對這些新功能的簡短概述,沏好茶,讓咱們一塊兒開始吧~前端

動態引入,import()

ES2015中提到到了static import語法,即普通的引用語法。讓你能夠從一個模塊導出一個變量,而後,直接在另一個模塊中引用。java

下面的代碼爲靜態引用的例子:web

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

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

console.log(splitName("John Snow"));

這種語法被稱爲靜態引用,是由於你沒有辦法在運行時經過某種條件來動態的引用某一個模塊。可是請注意,這不必定是壞事,靜態引用容許你在編譯時經過Tree Shaking來優化代碼(動態的引入使用到的代碼,減小打包的bundle包大小)。編程

另外一方面,若是可以合理的利用動態引用,也能夠經過按需加載依賴包的方式,減小bundle包的大小。數組

新的動態引用的語法看起來像一個函數(可是,他並非函數),它返回一個promise,這意味着咱們可使用async/await。來看個例子promise

// 根據條件動態選擇須要加載的模塊
const mod = figure.kind === "rectangle" ? "rectangle.js" : "circle.js";
// 等待模塊加載完成
const { calcSquare } = await import(mod);
console.log(calcSquare(figure));

空位合併,新運算符 ??

經過||運算符來設置一個值的默認值有它的缺陷。由於它並非真正的檢查值是否爲,它僅僅是檢查這個值是否爲。當一個值爲false或者0時,這個設置默認值的方法就會出問題。瀏覽器

ES2020提供了一種新的運算符??,它和||的工做原理很相似,可是,它僅僅在初始值爲null或者undefined時纔會取右側的值。機器學習

這裏有一個簡單的示例:async

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遊戲引擎入門系列》上,由於實在拖的過久啦,對不住本身年前定的計劃。

最近,搞了一個公衆號,你們有興趣的話關注一下,咱們一塊兒交流前端知識~

qrcode.png

好啦,翻譯完畢啦,原文連接在此 What's new in ECMAScript 2020

相關文章
相關標籤/搜索