咱們最喜歡的編程語言JavaScript的第11版規範草案ECMAScript2020中包含了不少新功能。其中一些是小的特性,也有一些特性擁有永久改變咱們編寫JavaScript方式的潛力。前端
本文是對這些新功能的簡短概述,沏好茶,讓咱們一塊兒開始吧~web
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
複製代碼
可選鏈操做符?.
設計的目的是爲了讓咱們在檢查多層嵌套的對象的某個屬性是否存在時,不須要去寫冗長的代碼。
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
是一個新的對象,用來表示大於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
複製代碼
這裏有一個例子,想象一下你有一個很長的字符串,而且你須要提取出來全部以#
開頭的詞。
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.all
函數麼?當全部promise都觸發了resolve
狀態,它纔會進入resolve
狀態。可是,當其中一個promise進入了reject
狀態,整個Promise.all
就會直接進入reject
狀態,不管其餘promise是否還處在pending
狀態。
Promise.allSettled
的表現和Promise.all
不同。當全部promise完成工做了,它會進入resolve
狀態,不管,這些promise是進入了resolve
或者reject
。它會將全部promise的處理結果都經過resolve函數返回出來。
所以,allSettled
沒有reject
狀態,他只有pending
和resolve
狀態。
下面是一個是現實世界的問題:去除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()
複製代碼
在JavaScript中,有一個包含任何東西的巨大上下文。通常來講,在瀏覽器中它是window
對象。在Node
應用它又變成了global
對象。到了webWorker中,它又變成了self
對象。
新的globalThis
屬性消除了環境帶來的差別性,你可使用globalThis
引入而不須要關心你所處的上下文。
若是你認爲這個命名有點尷尬,我徹底贊成您的意見,可是請注意,以self
或global
命名可能會不兼容某些較舊的代碼。因此我想咱們必須忍受這一點。
我是一個莫得感情的代碼搬運工,如今主要精力會投在更新《Laya2.x遊戲引擎入門系列》上,由於實在拖的過久啦,對不住本身年前定的計劃。
最近,搞了一個公衆號,你們有興趣的話關注一下,咱們一塊兒交流前端知識~
好啦,翻譯完畢啦,原文連接在此 What's new in ECMAScript 2020。