ECMAScript 2020 的新功能速成

翻譯:瘋狂的技術宅
原文: https://www.strictmode.io/art...
未經容許嚴禁轉載

ECMAScript 2020 是咱們最喜歡的編程語言的第 11 版,其中包含一些新功能。有些是小特性,但有些將會有可能永遠改變咱們編寫 JavaScript 的方式。javascript

Dynamic 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 Shakingjava

另外一方面,若是合理地使用了動態導入,則能夠經過按需加載依賴項來幫助減小分發包的大小。webpack

新的 dynamic import 語法看起來像一個函數(但不是),它返回 promise,這也意味着能夠將其與 async/await一塊兒使用。程序員

// ...
const mod = figure.kind === "rectangle" ? "rectangle.js" : "circle.js";
const { calcSquare } = await import(mod);
console.log(calcSquare(figure));

空值合併

流行的用 short-circuting 設置默認值的方法有其缺陷。因爲它實際上不是在檢查空值,而是在檢查是否爲,所以它會以諸如 false 0(二者均被視爲假)。web

ES2020引入了一個新的運算符 ??,該運算符的工做原理與其相似,但僅在初始值爲 nullundefined 時才賦值爲右手。面試

這是一個簡單的例子:正則表達式

const initialVal = 0;

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

// new way
const myVar = initialVal ?? 10; // => 0

可選鏈

新的 optional chaining 運算符用來在處理嵌套對象並檢查可能的 undefineds 時使代碼更短。編程

const user = { name: "John" };

// Fails with `Uncaught TypeError: Cannot read property 'city' of undefined`
const city = user.address.city;

// Works but verbose
let city = "Not Set";
if (user.address !== undefined && user.address !== null) {
  city = user.address.city;
}

// Works and concise but requires a 3rd party library
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 類型就可以派上用場了。segmentfault

它帶有本身的字面量表示法(只需在數字末尾添加 n):

const x = 9007199254740991n;

// or it can be constructed from a string
const y = BigInt("9007199254740991234");

BigInts 帶有本身的代數方法,它不能轉換爲常規數字,所以咱們不能把 number 與 BigInt 混淆。應該先將它們強制轉換爲任一類型。

1 === 1n; // => false
1n + 1; // throws Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
6n << 3; // nope
6n << 3n; // that works

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)]

matchAll 返回一個迭代器。咱們能夠用 for..of 對其進行迭代,也能夠將其轉換爲數組。

Promise.allSettled

還記得 Promise.all 函數嗎?它僅在全部的 Promise 均獲得解決時纔會被解決。假如其中有一項 Promise 被拒絕,此時可能還有其餘 promise 沒完成。

新的 allSettled 的行爲有所不一樣。只有當全部的 promise 所有都完成時(即成功或被拒絕),它纔會被解決。它被分解爲一個數組,其中包含 promise 的狀態及其所解決的內容(或錯誤)。

所以, allSettled 永遠不會被拒絕。它要麼是 pending,要麼是 resolved

一個現實中的問題是刪除加載指示器:

// const urls = [...]
try {
  await Promise.all(urls.map(fetch))
} catch (e) {
  // at least one fetch is rejected here, but there may others still pending
  // so it may be too early for removing the loading indicator
  removeLoading()
}

// with allSettled
await Promise.allSettled(urls.map(fetch))
removeLoading()

globalThis

在 JavaScript 中,老是有一個包含全部內容的大型上下文對象。傳統上,在瀏覽器中是 window。可是,若是嘗試在 Node 程序中訪問它,則會收到錯誤消息。 Node 中沒有 window 全局對象;而是有一個 window 對象。另外在 WebWorker 中,沒有訪問 window 的權限,可是有 self 的權限。

新的 globalThis 屬性能夠消除差別。這意味着你能夠自始至終去引用 globalThis,而無需關心你如今所處的上下文是什麼。

若是你認爲這命名有點尷尬,那麼我徹底贊成你的見解,可是請注意,將其命名爲 selfglobal 可能會使某些舊代碼不兼容。因此我想咱們必須忍受這一點。

有用的連接

爲了方便你的學習,這裏是本文提到的每一個功能的 MDN 文檔的連接。


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索