JavaScript ES2021 最值得期待的 5 個新特性解析

在寫本文時,本文提到的新的 JavaScript 提案功能已進入第 4 階段,而且幾乎確定會包含在 ES2021 中。你已經能夠開始在 最新版本的瀏覽器,Node.js 和 Babel 中使用前端

注意:ECMAScript 是 JavaScript 所基於的標準,由 TC39 委員會管理。ECMAScript 始終是一個不須要的名稱,這會使一切都對初學者感到困惑。人們常常談論 JavaScript 功能,但參考的是 ECMAScript 規範。git

更新特性github

1. 數值分隔符

大數字文字很難令人眼快速解析,尤爲是當有不少重複的數字時:正則表達式

1000000000000   1019436871.42

爲了提升可讀性,新的 JavaScript 語言功能 啓用了下劃線做爲數字文字中的分隔符。所以,上面的內容如今能夠重寫爲每千位數字,例如:編程

1_000_000_000_000    1_019_436_871.42

如今,更容易說出第一個數字是 1 萬億,而第二個數字大約是 10 億。api

數字分隔符有助於提升各類數字文字的可讀性:promise

// A decimal integer literal with its digits grouped per thousand:
1_000_000_000_000
// A decimal literal with its digits grouped per thousand:
1_000_000.220_720
// A binary integer literal with its bits grouped per octet:
0b01010110_00111000
// A binary integer literal with its bits grouped per nibble:
0b0101_0110_0011_1000
// A hexadecimal integer literal with its digits grouped by byte:
0x40_76_38_6A_73
// A BigInt literal with its digits grouped per thousand:
4_642_473_943_484_686_707n

它們甚至適用於八進制整數文字(儘管 我想不出 其中分隔符爲此類文字提供值 的示例):瀏覽器

// A numeric separator in an octal integer literal: 🤷♀️
0o123_456

請注意,JavaScript 還具備不帶顯式 0o 前綴的八進制文字的舊式語法。例如,017 === 0o17。在嚴格模式下或模塊內不支持此語法,而且在現代代碼中不該使用此語法。所以,這些文字不支持數字分隔符。使用 0o17 風格的文字代替。babel

2. Promise combinators

自從 ES2015 中引入 Promise 以來,JavaScript 徹底支持兩種 Promise 組合器:靜態方法 Promise.all 和 Promise.race。less

目前有兩個新提案正在經過標準化流程:Promise.allSettled 和 Promise.any。有了這些添加,JavaScript 中將總共有四個諾言組合器,每一個組合器支持不一樣的用例。

如下是這四個組合器的概述:

2.1 Promise.allSettled

Promise.allSettled 給你當全部輸入的諾言是一種信號結算,這意味着他們要麼履行或拒絕。若是您不在意承諾的狀態,而只是想知道工做什麼時候完成,不管它是否成功,這都是頗有用的。

例如,您能夠啓動一系列獨立的 API 調用,並使用 Promise.allSettled 它們來確保它們已所有完成,而後再執行其餘操做,例如刪除加載微調器:

const promises = [
  fetch('/api-call-1'),
  fetch('/api-call-2'),
  fetch('/api-call-3'),
];
// Imagine some of these requests fail, and some succeed.

await Promise.allSettled(promises);
// All API calls have finished (either failed or succeeded).
removeLoadingIndicator();

2.2 Promise.any

Promise.any 方法和 Promise.race 相似——只要給定的迭代中的一個 promise 成功,就採用第一個 promise 的值做爲它的返回值,但與 Promise.race 的不一樣之處在於——它會等到全部 promise 都失敗以後,才返回失敗的值:

const promises = [
  fetch('/endpoint-a').then(() => 'a'),
  fetch('/endpoint-b').then(() => 'b'),
  fetch('/endpoint-c').then(() => 'c'),
];
try {
  const first = await Promise.any(promises);
  // Any of the promises was fulfilled.
  console.log(first);
  // → e.g. 'b'
} catch (error) {
  // All of the promises were rejected.
  console.assert(error instanceof AggregateError);
  // Log the rejection values:
  console.log(error.errors);
  // → [
  //     <TypeError: Failed to fetch /endpoint-a>,
  //     <TypeError: Failed to fetch /endpoint-b>,
  //     <TypeError: Failed to fetch /endpoint-c>
  //   ]
}

此代碼示例檢查哪一個端點響應最快,而後將其記錄下來。只有當 全部 請求都失敗時,咱們才最終進入代碼 catch 塊,而後在其中處理錯誤。

Promise.any 拒絕能夠一次表明多個錯誤。 爲了在語言級別支持此功能,引入了一種新的錯誤類型,稱爲 AggregateError。 除了上面示例中的基本用法外,還能夠以編程方式構造 AggregateError 對象,就像其餘錯誤類型同樣:

const aggregateError = new AggregateError([errorA, errorB, errorC], 'Stuff went wrong!');

3. Weak references and finalizers

此功能包含兩個高級對象 WeakRefFinalizationRegistry。根據使用狀況,這些接口能夠單獨使用,也能夠一塊兒使用。正確使用它們須要仔細考慮,若是可能,最好避免使用它們。

通常來講,在JavaScript中,對象的引用是強保留的,這意味着只要持有對象的引用,它就不會被垃圾回收。

const ref = { x: 42, y: 51 };
// 只要咱們訪問 ref 對象(或者任何其餘引用指向該對象),這個對象就不會被垃圾回收

目前在 Javascript 中,WeakMap 和 WeakSet 是弱引用對象的惟一方法:將對象做爲鍵添加到 WeakMap 或 WeakSet 中,是不會阻止它被垃圾回收的。

JavaScript 的 WeakMap 並非真正意義上的弱引用:實際上,只要鍵仍然存活,它就強引用其內容。WeakMap 僅在鍵被垃圾回收以後,才弱引用它的內容。

WeakRef 是一個更高級的 API,它提供了真正的弱引用,Weakref 實例具備一個方法 deref,該方法返回被引用的原始對象,若是原始對象已被收集,則返回 undefined 對象。

JavaScript 中對象的引用是強引用,WeakMap 和 WeakSet 能夠提供部分的弱引用功能,若想在 JavaScript 中實現真正的弱引用,能夠經過配合使用 WeakRef 和終結器(Finalizer)來實現。

WeakRef 是用來指目標對象不脫離垃圾收集保留它的對象。若是未經過垃圾回收回收目標對象,則 WeakRefs 能夠取消引用以容許訪問目標對象。

// Create a WeakRef object referring to a given target object
const ref = new WeakRef(targetObject)

// Return the WeakRef instance's target object, or undefined if the target object has been garbage-collected
const obj = ref.deref()

使用 FinalizationRegistry 對象能夠在垃圾回收對象時請求回調。

// Create a registry object that uses the given callback
const registry = new FinalizationRegistry([callback])

// Register an object with a registry instance so that if the object is garbage-collected, the registry's callback may get called
registry.register(target, heldValue, [unregisterToken])

// Unregister a target object from a registry instance
registry.unregister(unregisterToken)

更多信息:TC39提案V8

4. String.prototype.replaceAll

當前,若是不使用全局正則表達式,就沒法替換字符串中子字符串的全部實例。與字符串參數一塊兒使用時,String.prototype.replace 僅影響首次出現。

String.prototype.replaceAll() 將爲開發人員提供一種簡單的方法來完成此常見的基本操做。

'aabbcc'.replaceAll('b', '.') // 'aa..cc'
'aabbcc'.replaceAll(/b/g, '.') // 'aa..cc'

5. Logical assignment (邏輯分配)

支持與新的運營邏輯分配 &&=||=??=。與它們的 數學和按位對應物不一樣,邏輯分配遵循其各自邏輯操做的短路行爲。僅當邏輯運算將評估右側時,它們才執行分配。

// falsy: false, 0, -0, 0n, "", null, undefined, and NaN
// truthy: all values are truthy unless defined as falsy
// nullish: null or undefined

a ||= b
// Logical OR assignment
// Equivalent to: a || (a = b);
// Only assigns if a is falsy

a &&= b
// Logical AND assignment
// Equivalent to: a && (a = b);
// Only assigns if a is truthy

a ??= b
// Logical nullish assignment
// Equivalent to: a ?? (a = b);
// Only assigns if a is nullish

5.1 具體例子

帶有 && 運算符的邏輯賦值運算符

僅當 LHS 值爲真時,纔將 RHS 變量值賦給 LHS 變量。

// Logical Assignment Operator with && operator
let num1 = 5
let num2 = 10
num1 &&= num2
console.log(num1) // 10
// Line 5 can also be written as following ways
// 1. num1 && (num1 = num2)
// 2. if (num1) num1 = num2

帶有 || 的運算符邏輯賦值運算符

僅當 LHS 值爲假時,纔將 RHS 變量值賦給 LHS 變量。

// Logical Assignment Operator with || operator
let num1
let num2 = 10
num1 ||= num2
console.log(num1) // 10
// Line 5 can also be written as following ways
// 1. num1 || (num1 = num2)
// 2. if (!num1) num1 = num2

帶有 ?? 運算符的邏輯賦值運算符

ES2020 引入了空值合併運算符,其也能夠與賦值運算符結合使用。
僅當 LHS 爲 undefined 或僅爲 null 時,纔將 RHS 變量值賦給 LHS 變量。

// Logical Assignment Operator with ?? operator
let num1
let num2 = 10
num1 ??= num2
console.log(num1) // 10
num1 = false
num1 ??= num2
console.log(num1) // false
// Line 5 can also be written as following ways
// num1 ?? (num1 = num2)

歸納

做爲開發人員,跟緊語言的新特性是很重要的。

以上將在 2021 年發佈的一些新功能,它們是進入第 4 階段的提案,幾乎能夠確定會包括在內,這些功能已經在最新的瀏覽器和 babel 中實現。

歡迎關注公衆號: 「全棧修煉」,回覆 「電子書」 便可以得到 160 本前端精華書籍哦。

參考文章:JavaScript Features in 2021

往期精文

經過閱讀本篇文章,若是有收穫的話,能夠點個贊在看,這將會成爲我持續分享的動力,感謝~

相關文章
相關標籤/搜索