<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JavaScript ES2021 最值得期待的 5 個(gè)新特性解析

          共 9000字,需瀏覽 18分鐘

           ·

          2021-03-29 15:29

          在寫(xiě)本文時(shí),本文提到的新的 JavaScript 提案功能已進(jìn)入第 4 階段,并且?guī)缀蹩隙〞?huì)包含在 ES2021 中。你已經(jīng)可以開(kāi)始在 最新版本的瀏覽器,Node.js 和 Babel 中使用。

          注意:ECMAScript 是 JavaScript 所基于的標(biāo)準(zhǔn),由 TC39 委員會(huì)管理。ECMAScript 始終是一個(gè)不需要的名稱,這會(huì)使一切都對(duì)初學(xué)者感到困惑。人們經(jīng)常談?wù)?JavaScript 功能,但參考的是 ECMAScript 規(guī)范。

          更新特性

          • 數(shù)字分隔符(_
          • 邏輯分配(&&=||=??=
          • 引用不足(WeakRefFinalizationRegistry
          • Promise.any
          • String.prototype.replaceAll

          1. 數(shù)值分隔符

          大數(shù)字文字很難使人眼快速解析,尤其是當(dāng)有很多重復(fù)的數(shù)字時(shí):

          1000000000000   1019436871.42

          為了提高可讀性,新的 JavaScript 語(yǔ)言功能 啟用了下劃線作為數(shù)字文字中的分隔符。因此,上面的內(nèi)容現(xiàn)在可以重寫(xiě)為每千位數(shù)字,例如:

          1_000_000_000_000    1_019_436_871.42

          現(xiàn)在,更容易說(shuō)出第一個(gè)數(shù)字是 1 萬(wàn)億,而第二個(gè)數(shù)字大約是 10 億。

          數(shù)字分隔符有助于提高各種數(shù)字文字的可讀性:

          // 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

          它們甚至適用于八進(jìn)制整數(shù)文字(盡管 我想不出 其中分隔符為此類文字提供值 的示例):

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

          請(qǐng)注意,JavaScript 還具有不帶顯式 0o 前綴的八進(jìn)制文字的舊式語(yǔ)法。例如,017 === 0o17。在嚴(yán)格模式下或模塊內(nèi)不支持此語(yǔ)法,并且在現(xiàn)代代碼中不應(yīng)使用此語(yǔ)法。因此,這些文字不支持?jǐn)?shù)字分隔符。使用 0o17 風(fēng)格的文字代替。

          2. Promise combinators

          自從 ES2015 中引入 Promise 以來(lái),JavaScript 完全支持兩種 Promise 組合器:靜態(tài)方法 Promise.all 和 Promise.race。

          目前有兩個(gè)新提案正在通過(guò)標(biāo)準(zhǔn)化流程:Promise.allSettled 和 Promise.any。有了這些添加,JavaScript 中將總共有四個(gè)諾言組合器,每個(gè)組合器支持不同的用例。

          以下是這四個(gè)組合器的概述:

          2.1 Promise.allSettled

          Promise.allSettled 給你當(dāng)所有輸入的諾言是一種信號(hào)結(jié)算,這意味著他們要么履行或拒絕。如果您不在乎承諾的狀態(tài),而只是想知道工作何時(shí)完成,無(wú)論它是否成功,這都是很有用的。

          例如,您可以啟動(dòng)一系列獨(dú)立的 API 調(diào)用,并使用 Promise.allSettled 它們來(lái)確保它們已全部完成,然后再執(zhí)行其他操作,例如刪除加載微調(diào)器:

          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 類似——只要給定的迭代中的一個(gè) promise 成功,就采用第一個(gè) promise 的值作為它的返回值,但與 Promise.race 的不同之處在于——它會(huì)等到所有 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>
            //   ]
          }

          此代碼示例檢查哪個(gè)端點(diǎn)響應(yīng)最快,然后將其記錄下來(lái)。只有當(dāng) 所有 請(qǐng)求都失敗時(shí),我們才最終進(jìn)入代碼 catch 塊,然后在其中處理錯(cuò)誤。

          Promise.any 拒絕可以一次代表多個(gè)錯(cuò)誤。為了在語(yǔ)言級(jí)別支持此功能,引入了一種新的錯(cuò)誤類型,稱為 AggregateError。除了上面示例中的基本用法外,還可以以編程方式構(gòu)造 AggregateError 對(duì)象,就像其他錯(cuò)誤類型一樣:

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

          3. Weak references and finalizers

          此功能包含兩個(gè)高級(jí)對(duì)象 WeakRefFinalizationRegistry。根據(jù)使用情況,這些接口可以單獨(dú)使用,也可以一起使用。正確使用它們需要仔細(xì)考慮,如果可能,最好避免使用它們。

          一般來(lái)說(shuō),在JavaScript中,對(duì)象的引用是強(qiáng)保留的,這意味著只要持有對(duì)象的引用,它就不會(huì)被垃圾回收。

          const ref = { x42y51 };
          // 只要我們?cè)L問(wèn) ref 對(duì)象(或者任何其他引用指向該對(duì)象),這個(gè)對(duì)象就不會(huì)被垃圾回收

          目前在 Javascript 中,WeakMap 和 WeakSet 是弱引用對(duì)象的唯一方法:將對(duì)象作為鍵添加到 WeakMap 或 WeakSet 中,是不會(huì)阻止它被垃圾回收的。

          JavaScript 的 WeakMap 并不是真正意義上的弱引用:實(shí)際上,只要鍵仍然存活,它就強(qiáng)引用其內(nèi)容。WeakMap 僅在鍵被垃圾回收之后,才弱引用它的內(nèi)容。

          WeakRef 是一個(gè)更高級(jí)的 API,它提供了真正的弱引用,Weakref 實(shí)例具有一個(gè)方法 deref,該方法返回被引用的原始對(duì)象,如果原始對(duì)象已被收集,則返回 undefined 對(duì)象。

          JavaScript 中對(duì)象的引用是強(qiáng)引用,WeakMap 和 WeakSet 可以提供部分的弱引用功能,若想在 JavaScript 中實(shí)現(xiàn)真正的弱引用,可以通過(guò)配合使用 WeakRef 和終結(jié)器(Finalizer)來(lái)實(shí)現(xiàn)。

          WeakRef 是用來(lái)指目標(biāo)對(duì)象不脫離垃圾收集保留它的對(duì)象。如果未通過(guò)垃圾回收回收目標(biāo)對(duì)象,則 WeakRefs 可以取消引用以允許訪問(wèn)目標(biāo)對(duì)象。

          // 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 對(duì)象可以在垃圾回收對(duì)象時(shí)請(qǐng)求回調(diào)。

          // 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

          當(dāng)前,如果不使用全局正則表達(dá)式,就無(wú)法替換字符串中子字符串的所有實(shí)例。與字符串參數(shù)一起使用時(shí),String.prototype.replace 僅影響首次出現(xiàn)。

          String.prototype.replaceAll() 將為開(kāi)發(fā)人員提供一種簡(jiǎn)單的方法來(lái)完成此常見(jiàn)的基本操作。

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

          5. Logical assignment (邏輯分配)

          支持與新的運(yùn)營(yíng)邏輯分配 &&=||=??=。與它們的 數(shù)學(xué)和按位對(duì)應(yīng)物不同,邏輯分配遵循其各自邏輯操作的短路行為。僅當(dāng)邏輯運(yùn)算將評(píng)估右側(cè)時(shí),它們才執(zhí)行分配。

          // 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 具體例子

          帶有 && 運(yùn)算符的邏輯賦值運(yùn)算符

          僅當(dāng) LHS 值為真時(shí),才將 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

          帶有 || 的運(yùn)算符邏輯賦值運(yùn)算符

          僅當(dāng) LHS 值為假時(shí),才將 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

          帶有 ?? 運(yùn)算符的邏輯賦值運(yùn)算符

          ES2020 引入了空值合并運(yùn)算符,其也可以與賦值運(yùn)算符結(jié)合使用。僅當(dāng) LHS 為 undefined 或僅為 null 時(shí),才將 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)

          概括

          作為開(kāi)發(fā)人員,跟緊語(yǔ)言的新特性是很重要的。

          以上將在 2021 年發(fā)布的一些新功能,它們是進(jìn)入第 4 階段的提案,幾乎可以肯定會(huì)包括在內(nèi),這些功能已經(jīng)在最新的瀏覽器和 babel 中實(shí)現(xiàn)。

          參考文章:JavaScript Features in 2021

          可以加貓哥的 wx:CB834301747 ,一起閑聊前端。

          微信搜 “全棧修煉”,回復(fù) “電子書(shū)” 即可以獲得 160 本前端精華書(shū)籍哦。

          往期精文

          通過(guò)閱讀本篇文章,如果有收獲的話,可以點(diǎn)個(gè)贊在看,這將會(huì)成為我持續(xù)分享的動(dòng)力,感謝~

          瀏覽 84
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色色91 | 天天艹天天操 | 免费高清无码在线 | 婷婷五月天黄色 | 欧美日韩午夜激情 |