ECMAScript 2020(ES11)新特性簡介

簡介

ES11是ECMA協會在2020年6月發行的一個版本,因爲是ECMAScript的第十一個版本,所以也稱爲ES11.

今天我們講解一下ES11的新特性。

ES11引入了9個新特性,我們接下來一一講解。

動態imports

在ES11之前,我們可以使用下面的方式進行模塊的導入:

import * as TestModule from "./test-module.js";

但是上面的導入方式會有一些問題,首先是效率的問題,所有的module都需要在首次加載的時候導入,會導致程序效率的降低。另外上面的模塊名字是寫死的,不可以在程序運行的時候進行動態修改。

也就是說上面的模塊導入方式,不能對模塊進行動態導入,或者按需導入,在使用上有諸多的不便。

爲了解決這個問題,ES11引入了新的import() 方法,使用這個方法,你可以對模塊進行動態導入,並且通過設置模塊名爲變量的形式,可以對模塊名進行動態修改,非常的神奇。我們看一個具體的使用例子:

const baseModulePath = "./baseModules";
const btnImportModule = document.getElementById("btnImportModule");
let userList = [];

btnImportModule.addEventListener("click", async e => {
  const userModule = await import(`${baseModulePath}/users.js`);

  userList = userModule.getUsers();
});

上面代碼中我們定義了一個基本的Module路徑,通過點擊頁面上的按鈕,可以動態的加載一個users.js模塊,然後調用該模塊的getUsers()方法,獲得userList列表。

import.meta

除了動態引入模塊之外,import還提供了一個元屬性meta,它包含了當前引入的模塊的信息,目前他裏面有一個url屬性,代表模塊被引用的URL。如果想使用URL信息,那麼可以在代碼中使用import.meta.url。

export加強

import是在ECMAScript 2015中引入的,主要被用來做模塊的引入,import可以引入整個模塊,也可以引入部分模塊。如下所示:

import {something} from "./test-module.js";
import * from "./test-module.js";

和import對應的就是export,同樣可以export所有或者部分,如下所示:

export {something} from "./test-module.js";
export * from "./test-module.js";

通常情況來說,上面講的import和export已經夠用了,但是對於導出模塊需要重命名的情況,我們不能直接導出,而是必須先在import的時候進行重命名,然後再使用export將重命名的模塊導出:

import * as myModule from "./test-module.js";
export {myModule};

如果使用export的增強,則不需要使用import,直接使用export導出即可:

export * as {myModule} from "./test-module.js";

BigInt

ES11引入了新的數據類型BigInt,在這之前,javascript中表示數字的對象是Number,它可以表示64-bit的浮點類型數字。當然它也可以代表整數,但是整數表示的最大值是2^53,也可以用Number.MAX_SAFE_INTEGER來表示。

一般來說Number已經夠用了,但是如果在某些情況下需要對64-bit的整數進行存儲或者運算,或者要表示的範圍超過了64-bit的話,Number就不夠用了。

怎麼辦呢?如果只是存儲的話,可以存儲爲字符串,但是第二種字符串就不適用了。於是引入了BigInt來解決這個問題。要表示BigInt,只需要在數字的後面加上n即可。

const bigInt = 112233445566778899n;

或者使用構造函數來構造bigInt:

const bigInt = BigInt("112233445566778899");

可以使用typeof來查看bigInt的類型。要注意的是雖然Number和BigInt都代表的是數字,但是兩者是不能混用的,你不能將一個Number和一個BigInt相加。這會報TypeError異常。

如果非要進行操作,那麼可以使用BigInt構造函數將Number轉換成爲BigInt之後再進行。

matchAll()

正則表達式的匹配是一個非常常見的操作,通常我們使用regExp.exec來進行正則的匹配,舉個正則匹配的例子如下:

const regExp = /yyds(\d+)/g;
const text = 'yyds1 is a very good yyds2';
let matches;

while ((matches = regExp.exec(text)) !== null) {
  console.log(matches);
}

上面的代碼運行結果如下:

["yyds1","1"]
["yyds2","2"]

我們得到了所有匹配的值。不過需要使用一個循環來進行遍歷,使用起來有諸多的不便,爲了簡單起見,ES11引入了matchAll()方法。這個方法可以簡單的返回一個遍歷器,通過遍歷這個遍歷器,就可以得到所有的匹配的值,如下所示:

const regExp = /yyds(\d+)/g;
const text = 'yyds1 is a very good yyds2';
let matches = [...text.matchAll(regExp)];

for (const match of matches) {
  console.log(match);
}

globalThis

對於javascript來說,不同的環境對應的全局對象的獲取方式也是不同的,對於瀏覽器來說通常使用的是window,但是在web worker中使用的是self,而在nodejs中使用的是global。

爲了解決在不同環境中的全局對象不同的問題,ES11引入了globalThis,通過這個全局對象,程序員就不用再去區分到底是在哪個環境下了,只需要使用globalThis即可。

Promise.allSettled()

自從Promise引入之後,有兩個方法可以對Promise進行組合,分別是Promise.all() 和Promise.race(), 他們分別表示返回所有的Promise和返回最快的那個。

對於Promise.all()來說,它會等待所有的Promise都運行完畢之後返回,如果其中有一個Promise被rejected,那麼整個Promise.all()都會被rejected。在這種情況下,如果有一個Promise被rejected,其他的Promise的結果也都獲取不了。

爲了解決這個問題,ES11引入了Promise.allSettled() 方法,這個方法會等待所有的Promise結束,不管他們是否被rejected,所以可以使用下面的代碼獲得所有的結果,而不管其中是否有Promise出現問題。

const promises = [promise1("/do1"), promise2("/do2")];
const allResults = await Promise.allSettled(promises);
const errors = results
  .filter(p => p.status === 'rejected')
  .map(p => p.reason);

??操作符

??操作符是一個判斷是否爲空然後賦值的操作,如果沒有這個操作符,我們通常使用||來簡單的進行這個操作,如下所示:

const yourAge = someBody.age || 18

上面的代碼意思是如果someBody.age 是空,那麼就將yourAge設置成爲18。

但是上面代碼有個問題,如果someBody.age=0 的話,上述邏輯也成立。使用??操作符可以解決這個問題。

const yourAge = someBody.age ?? 18

?.操作符

我們有時候在獲取某個對象的屬性的時候,需要進行對象的null判斷,否則從null對象中取出屬性就會報錯,但是通常的?:操作符使用起來太複雜了,如果有多個對象和屬性連寫的情況下更是如此,如果使用?.操作符就會簡單很多:

const age = school?.class?.student?.age;

如上所示,這個一個非常複雜的連寫操作,但是使用?.就變得很簡單。

同樣?.還可以用在對象的方法上:

const age = student.getAge?.();

上面代碼表示,如果student的getAge方法存在,則調用,否則返回undefined。

總結

事實上所有的現代瀏覽器基本上都支持ES11了,IE除外。大家可以盡情嘗試ES11的新特徵。

本文已收錄於 http://www.flydean.com/ecmascript-11/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,衆多你不知道的小技巧等你來發現!

歡迎關注我的公衆號:「程序那些事」,懂技術,更懂你!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章