Categories
程式開發

ECMAScript 2020 的新功能


JavaScript 是很受歡迎的前端開發語言之一,而 ECMAScript 在推進 JavaScript 發展上有著不可磨滅的貢獻。 2015年6月正式發布的 ECMAScript 6.0(以下簡稱 ES6)是 JavaScript 語言的下一代標準,它的目標,是使得 JavaScript 語言可以用來編寫複雜的大型應用程序,成為企業級開發語言。 ECMAScript 2020 即將到來,讓我們先來看看有哪些新功能吧。

ECMAScript 和 JavaScript

JavaScript 作為前端最受歡迎的語言之一,每次更新新特性或者性能優化都會引發前端開發者的關注。那麼 ES 和 JS 有什麼區別呢?這個問題要回溯到1996年11月,JavaScript 的創造者 Netscape 公司希望能將這門語言制定成國際標準,於是將 JavaScript 提交至國際標準化組織 ECMA。次年,ECMA 發布了262號標准文件的第一版,規定了瀏覽器腳本語言的標準,並將這門語言稱為 ECMAScript,這個版本就是1.0版。

可以說,ECMAScript 這一標準從始至終就是針對 JavaScript 語言制定的,那為什麼不直接叫做 JavaScript 呢?主要有兩點原因:

首先是版權原因,Java 是 Sun 公司的商標,根據授權協議,只有 Netscape 公司可以合法地使用 JavaScript 這個名字,而且 JavaScript 也早已被 Netscape 公司註冊為商標。

其次,稱之為 ECMAScript 也是希望體現這門語言的規範是由 ECMA 制定,而不是 Netscape,這樣也能更好地保證這門語言的開放性和中立性。

綜上所述,ECMAScript 和 JavaScript 的關係就很好理清了,ES 是 JS 的規範,而 JS 是 ES 的一種實現方法。

ES 2020 的新功能

動態 import ()

靜態 import 語法最早於 ES 2015 引入,用於導入由另一個模塊導出的變量。該語法稱為靜態語法,因為開發者無法在運行時動態導入模塊,但靜態導入可以在編譯時進行優化。此外,還有一個類似函數的動態 import(),它不需要依賴 type="module" 的 script 標籤。如果合理地使用動態導入,則可以通過按需加載依賴項減少分發包的大小。

新的動態 import 語法看起來像一個函數,但並不是函數,不過動態 import 語法也支持await。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import

空值合併運算符

大家都知道,使用短循環設置默認值的方法有一個小缺陷,由於它實際上不是在檢查空值,而是在檢查結果的虛假性,因此它會破壞值為false 或0 的結果,因為兩者均被視為虛假性的結果。 ES2020引入了一個新的運算符 ?? ,該運算符的工作原理與短循環類似,但僅當初始值為null或 undefined 時才讀取為運算符右邊的值。

const nullValue = null;

const emptyText = ""; // falsy

const someNumber = 42;

const valA = nullValue ?? "default for A";

const valB = emptyText ?? "default for B";

const valC = someNumber ?? 0;

console.log(valA); // "default for A"

console.log(valB); // "" (as the empty string is not null or undefined)

console.log(valC); // 42

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

可選鏈接

新的 optional chaining 運算符旨在在處理嵌套對象和檢查可能的代碼時使代碼更短unde​​fineds。可選的鏈接運算符 ?. 允許讀取位於連接對象鏈深處的屬性的值,而不必明確驗證鏈中的每個引用是否有效。運算符的功能與 .chaining 運算符相似,不同之處在於,如果引用為空(null或undefined),則表達式會短路,返回值為 undefined。當與函數調用一起使用時,如果給定的函數不存在,則返回未定義的值。

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";

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

BigInt

BigInt是一個內置的對象,它提供了一種方法來表示大於 2⁵³-1 的整數,這是JavaScript可以可靠地用number原語表示的最大數,並由number表示。 MAX_SAFE_INTEGER常量。 BigInt可用於任意大整數。

這是一個計算素數的例子:

// Returns true if passed BigInt is a prime number

function isPrime(p) {

  for (let i = 2n; i * i = 0n) {

    if (isPrime(maybePrime)) {

      nth--

      prime = maybePrime

    }

    maybePrime++

  }

  

  return prime

}

nthPrime(20n)

// ↪ 73n

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt

globalThis

在JavaScript中,總會有一個包含了所有內容的很大的對象,但在傳統意義上來說,如果你嘗試在瀏覽器中打開它則是會報錯的。有的時候全局可以正常訪問的節點在瀏覽器中卻可以訪問,反之有些可以全局訪問的節點在瀏覽器中卻無法訪問,而新的globalThis屬性解決了這個問題。

在此之前globalThis,獲取環境全局對象的唯一可靠的跨平台方法是Function(‘return this’)()。但是,這會導致在某些設置中違反 CSP,因此 es6-shim 使用這樣的檢查,例如:

var getGlobal = function () { 

  if (typeof self !== 'undefined') { return self; } 

  if (typeof window !== 'undefined') { return window; } 

  if (typeof global !== 'undefined') { return global; } 

  throw new Error('unable to locate global object'); 

}; 

var globals = getGlobal(); 

if (typeof globals.setTimeout !== 'function') { 

  // no setTimeout in this environment! 

}

有了globalThis這個功能,就不再需要在整個環境中進行全局搜索:

if (typeof globalThis.setTimeout !== 'function') {

  // no setTimeout in this environment!

}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis

延伸閱讀

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference