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

          一覺醒來,竟發(fā)現(xiàn)自己看不懂 JS 了?

          共 19768字,需瀏覽 40分鐘

           ·

          2021-06-24 17:43

          作者:林不渡

          https://juejin.cn/post/6974330720994983950

          前言

          最近看到了一些很有趣的 ES 提案,如 Record 與 Tuple 數(shù)據(jù)類型,思路來自 RxJS 的 Observable,借鑒自函數(shù)式編程的 throw Expressions,帶來更好錯(cuò)誤處理的Error Cause等,可以認(rèn)為一旦這些提案完全進(jìn)入到 ES 新特性中,前端 er 們的工作效率又會(huì) upup,這篇文章就來介紹一下我認(rèn)為值得關(guān)注的 ES 提案。

          作為前端同學(xué),即使你沒有去主動(dòng)了解過,應(yīng)該也或多或少聽說過 ECMA、ECMAScript、TC39、ES6(這個(gè)當(dāng)然了)這些詞,你可能對(duì)這些名詞代表的概念一知半解甚至是從未了解過,但這很正常,不知道這些名詞的關(guān)系并不影響你將 ES 新特性用的如臂使指。但了解一下也不虧?所以在開始正式介紹各種提案前,我們有必要先了解一下這些概念。

          以下關(guān)于背景的介紹大部分來自于雪碧老師的JavaScript20 年-創(chuàng)立標(biāo)準(zhǔn)[1]一節(jié)。

          • ECMA(European Computer Manufacturers Association,歐洲計(jì)算機(jī)制造商協(xié)會(huì))[2],這是一個(gè)國際組織,主要負(fù)責(zé)維護(hù)各種計(jì)算機(jī)的相關(guān)標(biāo)準(zhǔn)。我們都知道 JavaScript 這門語言最早來自于網(wǎng)景(Netscape),但網(wǎng)景在和微軟(IE)的競(jìng)爭(zhēng)落得下風(fēng),為了避免最終 Web 腳本主導(dǎo)權(quán)落入微軟手中,網(wǎng)景開始尋求 ECMA 組織的幫助,來推動(dòng) JavaScript 的標(biāo)準(zhǔn)化。
          • 在 1996 年,JavaScript 正式加入了 ECMA 大家庭,我們后面會(huì)叫它 ECMAScript(下文簡(jiǎn)稱 ES)。TC39 則是 ECMA 為 ES 專門組織的技術(shù)委員會(huì)(Technical Committee),39 這個(gè)數(shù)字則是因?yàn)?ECMA 使用數(shù)字來標(biāo)記旗下的技術(shù)委員會(huì)。TC39 的成員由各個(gè)主流瀏覽器廠商的代表構(gòu)成(因?yàn)楫吘棺詈筮€要這些人實(shí)現(xiàn)嘛)。
          • ECMA-262 即為 ECMA 組織維護(hù)的第 262 條標(biāo)準(zhǔn),這一標(biāo)準(zhǔn)是在不斷演進(jìn)的,如現(xiàn)在是2020 年 6 月發(fā)布的第 11 版[3]。同樣的,目前最為熟知的是2015 年發(fā)布的 ES6[4]。你還可以在TC39 的 ECMA262 官網(wǎng)[5]上看到 ES2022 的最新草案。
          • ECMA 還維護(hù)著許多其他方面的標(biāo)準(zhǔn),如ECMA-414[6],定義了一組 ES 規(guī)范套件的標(biāo)準(zhǔn);ECMA-404[7],定義了 JSON 數(shù)據(jù)交換的語法;甚至還有 120mm DVD 的標(biāo)準(zhǔn):ECMA267[8]
          • 對(duì)于一個(gè)提案從提出到最后被納入 ES 新特性,TC39 的規(guī)范中有五步要走:
            • stage0(strawman),任何 TC39 的成員都可以提交。
            • stage1(proposal),進(jìn)入此階段就意味著這一提案被認(rèn)為是正式的了,需要對(duì)此提案的場(chǎng)景與 API 進(jìn)行詳盡的描述。
            • stage2(draft),演進(jìn)到這一階段的提案如果能最終進(jìn)入到標(biāo)準(zhǔn),那么在之后的階段都不會(huì)有太大的變化,因?yàn)槔碚撋现唤邮茉隽啃薷摹?/section>
            • state3(candidate),這一階段的提案只有在遇到了重大問題才會(huì)修改,規(guī)范文檔需要被全面的完成。
            • state4(finished),這一階段的提案將會(huì)被納入到 ES 每年發(fā)布的規(guī)范之中。
          • 有興趣的同學(xué)可以閱讀 The TC39 process for ECMAScript features[9] 了解更多。

          Record & Tuple(stage2)

          proposal-record-tuple[10] 這一提案為 JavaScript 新增了兩種數(shù)據(jù)結(jié)構(gòu):Record(類似于對(duì)象) 和 Tuple(類似于數(shù)組),它們的共同點(diǎn)是都是不可變的(Immutable),同時(shí)成員只能是原始類型以及同樣不可變的 Record 和 Tuple。正因?yàn)樗鼈兊某蓡T不能包含引用類型,所以它們是 按值比較 的,成員完全一致的 Record 和 Tuple 如果進(jìn)行比較,會(huì)被認(rèn)為是相同的('==='會(huì)返回 true)。

          你可能會(huì)想到社區(qū)其實(shí)對(duì)于數(shù)據(jù)不可變已經(jīng)有不少方案了,如 ImmutableJS 與 Immer。而數(shù)據(jù)不可變同樣是 React 中的重要概念。

          使用示例:

          // Record
          const proposal = #{
            id1234,
            title"Record & Tuple proposal",
            contents`...`,
            keywords: #["ecma""tc39""proposal""record""tuple"],
          };

          // Tuple
          const measures = #[421267"measure error: foo happened"];

          個(gè)人感想:會(huì)是很有用的新成員,尤其是在追求性能優(yōu)化下以及 React 項(xiàng)目中,gkdgkd。

          .at() Relative Indexing Method (stage 3)

          proposal-relative-indexing-method[11]提案引入了at()方法,用于獲取可索引類(Array, String, TypedArray)上指定位置的成員。

          在過去 JavaScript 中一直缺乏負(fù)索引相關(guān)的支持,比如獲取數(shù)組的最后一個(gè)成員需要使用arr[arr.length-1],而無法使用arr[-1]。這主要是因?yàn)?JavaScript 中[]可以對(duì)所有對(duì)象使用,所以arr[-1]返回的是 key 為-1的屬性值,而非索引為-1(從后往前排序)的數(shù)組成員。

          而要獲取數(shù)組的倒數(shù)第 N 個(gè)成員,通常使用的方法是arr[arr.length - N],或者arr.slice(-N)[0],兩種方法都有各自的缺陷,因此at()就來救場(chǎng)了。

          另外,還存在獲取數(shù)組最后一個(gè)成員的提案,proposal-array-last[12] (stage1)與獲取數(shù)組最后一個(gè)符合條件的成員的提案 proposal-array-find-from-last[13]

          個(gè)人感想:來得有點(diǎn)晚,但也不算晚。

          Temporal (stage 3)

          proposal-temporal[14]主要是為了提供標(biāo)準(zhǔn)化的日期與時(shí)間 API,這一提案引入了一個(gè)全局的命名空間 Temporal(類似于 Math、Promise)來引入一系列現(xiàn)代化的日期 API(JavaScript 的 Date API 誰用誰知道嗷,也難怪社區(qū)那么多日期處理庫了),如:

          • Temporal.Instant 獲取一個(gè)固定的時(shí)間對(duì)象:
          const instant = Temporal.Instant.from("1969-07-20T20:17Z");
          instant.toString(); // => '1969-07-20T20:17:00Z'
          instant.epochMilliseconds; // => -14182980000
          • Temporal.PlainDate 獲取 calendar date:
          const date = Temporal.PlainDate.from({ year2006month8day24 }); // => 2006-08-24
          date.year; // => 2006
          date.inLeapYear; // => false
          date.toString(); // => '2006-08-24'
          • Temporal.PlainTime 獲取 wall-clock time(和上面一樣,不知道咋翻譯):
          const time = Temporal.PlainTime.from({
            hour19,
            minute39,
            second9,
            millisecond68,
            microsecond346,
            nanosecond205,
          }); // => 19:39:09.068346205

          time.second; // => 9
          time.toString(); // => '19:39:09.068346205'
          • Temporal.Duration 獲取一段時(shí)間長度,用于比較時(shí)間有奇效
          const duration = Temporal.Duration.from({
            hours130,
            minutes20,
          });

          duration.total({ unit"second" }); // => 469200

          更多細(xì)節(jié)參考ts39-proposal-temporal docs[15]

          個(gè)人感想:同樣,來得有點(diǎn)晚,但也不算晚。

          Private Methods (stage 3)

          private-methods[16] 提案為 JavaScript Class 引入了私有屬性、方法以及 getter/setter,不同于 TypeScript 中使用private語法,這一提案使用#語法來標(biāo)識(shí)私有成員,在阮老師的ES6 標(biāo)準(zhǔn)入門[17]中也提到了這一提案。

          所以這個(gè)提案已經(jīng)過了多少年了...

          參考阮老師給的例子:

          class IncreasingCounter {
            #count = 0;
            get value() {
              console.log("Getting the current value!");
              return this.#count;
            }
            increment() {
              this.#count++;
            }
          }

          類似的,還有一個(gè)同樣處于 stage3 的提案proposal-class-fields[18]引入了static關(guān)鍵字。

          個(gè)人感想:對(duì)我來說用處比較小,因?yàn)楫吘苟际菍?TS,幾乎沒有什么機(jī)會(huì)在 JavaScript 中寫 Class 了。但是這一提案成功被引入后,可能會(huì)使得 TS 到 JS 的編譯產(chǎn)物變化,即直接使用 JS 自身的static#語法。比如現(xiàn)在這么一段 TS 代碼:

          class A {
            static x1 = 8;
          }

          編譯結(jié)果是:

          "use strict";
          class A {}
          A.x1 = 8;

          而在static被引入后,則會(huì)直接使用static語法。

          Top-level await (stage4)

          我記得這篇文章開始寫的時(shí)候,這個(gè)提案還在 stage3 的,我到底鴿了多久...

          proposal-top-level-await[19]這個(gè)提案感覺就沒有啥展開描述的必要了,很多人應(yīng)該已經(jīng)用上了。簡(jiǎn)單地說,就是你的await語法不再和async強(qiáng)綁定了,你可以直接在應(yīng)用的最頂層使用await語法,Node 也從 14.8 開始支持了這一提案。

          個(gè)人感想:可以少寫一個(gè) async 函數(shù)了,奈斯奧。

          Import Assertions (stage 3)

          proposal-import-assertions[20] 這一提案為導(dǎo)入語句新增了用于標(biāo)識(shí)模塊類型的斷言語句,語法如下:

          import json from "./foo.json" assert { type"json" };
          import("foo.json", { assert: { type"json" } });

          注意,對(duì) JSON 模塊的導(dǎo)入最開始屬于這一提案的一部分,后續(xù)被獨(dú)立出來作為一個(gè)單獨(dú)的提案:proposal-json-modules[21]

          這一提案最初起源于為了在 JavaScript 中更便捷的導(dǎo)入 JSON 模塊,后續(xù)出于安全性考慮加上了import assertions來作為導(dǎo)入不可執(zhí)行模塊的必須條件。

          這一提案同樣解決了模塊類型與其 MIME 類型不符的情況。

          個(gè)人感想:和現(xiàn)在如火如荼的 ESM、Bundleless 工具應(yīng)該會(huì)有奇妙的化學(xué)反應(yīng)。

          Decorators (stage 2)

          proposal-decorators[24]這一提案...,或許是我們最熟悉的老朋友了。但是此裝飾器非彼裝飾器,歷時(shí)五年來裝飾器提案已經(jīng)走到了第三版,仍然卡在 stage 2。

          這里引用我早前的一篇文章來簡(jiǎn)單講述下裝飾器的歷史:

          首先我們需要知道,JS 與 TS 中的裝飾器不是一回事,JS 中的裝飾器目前依然停留在 stage 2[25] 階段,并且目前版本的草案與 TS 中的實(shí)現(xiàn)差異相當(dāng)之大(TS 是基于第一版,JS 目前已經(jīng)第三版了),所以二者最終的裝飾器實(shí)現(xiàn)必然有非常大的差異。

          其次,裝飾器不是 TS 所提供的特性(如類型、接口),而是 TS 實(shí)現(xiàn)的 ECMAScript 提案(就像類的私有成員一樣)。TS 實(shí)際上只會(huì)對(duì)stage-3以上的語言提供支持,比如 TS3.7.5 引入了可選鏈(Optional chaining[26])與空值合并(Nullish-Coalescing[27])。而當(dāng) TS 引入裝飾器時(shí)(大約在 15 年左右),JS 中的裝飾器依然處于stage-1 階段。其原因是 TS 與 Angular 團(tuán)隊(duì) PY 成功了,Ng 團(tuán)隊(duì)不再維護(hù) [AtScript](<https://linbudu.top/posts/2020/08/10/atscript-playground[28]>),而 TS 引入了注解語法(Annotation)及相關(guān)特性。

          但是并不需要擔(dān)心,即使裝飾器永遠(yuǎn)到達(dá)不了 stage-3/4 階段,它也不會(huì)消失的。有相當(dāng)多的框架都是裝飾器的重度用戶,如AngularNestMidway等。對(duì)于裝飾器的實(shí)現(xiàn)與編譯結(jié)果會(huì)始終保留,就像JSX一樣。如果你對(duì)它的歷史與發(fā)展方向有興趣,可以讀一讀 是否應(yīng)該在 production 里使用 typescript 的 decorator?[29](賀師俊賀老的回答)

          個(gè)人感想:和類的私有成員、靜態(tài)成員提案一樣,目前使用最廣泛的還是 TS 中的裝飾器,但是二者的思路完全不同,因此我猜想原生裝飾器的提案不會(huì)影響 TypeScript 的編譯結(jié)果。

          Iterator Helpers (stage 2)

          proposal-iterator-helpers[30]提案為 ES 中的 Iterator 使用與消費(fèi)引入了一批新的接口,雖然實(shí)際上,如 Lodash 與Itertools[31](思路來自于 Python3 中的itertools[32])這樣的工具庫已經(jīng)提供了絕大部分能力,如 filter、filterMap 等。其他語言如 Rust、C#中也內(nèi)置了非常強(qiáng)大的 Iterator Helpers,見Prior Art[33]

          示例:

          functionnaturals({
            let i = 0;
            while (true) {
              yield i;
              i += 1;
            }
          }

          const evens = naturals().filter((n) => n % 2 === 0);

          for (const even of evens) {
            console.log(even, "is an even number");
          }

          個(gè)人感想:雖然目前很少會(huì)直接操作 Generator 和 Iterator 了,但這些畢竟是語言底部的東西,了解使用與機(jī)制還是有好處的。我上一次接觸 Iterator,還是為 Nx 編寫插件時(shí)為其提供 Async Iterator 接口,但也是直接囫圇吞棗的使用rxjs-for-await[34]這個(gè)庫。對(duì)這個(gè)提案的關(guān)注可能會(huì)相對(duì)少一些。

          throw Expressions (stage 2)

          proposal-throw-expressions[35]這一提案主要提供了const x = throw new Error()的能力,這并不是throw語法的替代品,更像是面向表達(dá)式(Expression-Oriented)的補(bǔ)齊。

          function getEncoder(encoding{
            const encoder =
              encoding === "utf8"
                ? new UTF8Encoder()
                : encoding === "utf16le"
                ? new UTF16Encoder(false)
                : encoding === "utf16be"
                ? new UTF16Encoder(true)
                : throw new Error("Unsupported encoding");
          }

          個(gè)人感想:錯(cuò)誤處理又可以更自然美觀一些了,奈斯!

          Set Methods (stage 2)

          proposal-set-methods[36]這一提案為 Set 新增了一批新的方法,如:

          • intersection/union/difference:基于交集/并集/差集創(chuàng)建新的 Set

          • isSubsetOf/isSupersetOf:判斷是否是子集/超集

          個(gè)人感想:Set 的話用的比較少,但很明顯這些方法會(huì)是一個(gè)不錯(cuò)的能力增強(qiáng)。

          Upsert(Map.prototype.emplace) (stage 2)

          proposal-upsert[37]這一提案為 Map 引入了 emplace 方法,在當(dāng)前 Map 上的 key 已存在時(shí),執(zhí)行更新操作,否則執(zhí)行創(chuàng)建操作。

          個(gè)人感想:確實(shí)是很甜的語法糖,感覺底層框架、工具庫用 Map 多一些。

          Observable (stage 1)

          proposal-observable[38]這一提案,其實(shí)懂的同學(xué)看到 Observable 已經(jīng)懂這個(gè)提案是干啥的了,它引入了 RxJS 中的 Observable、Observer(同樣是 next/error/complete/start)、Subscriber(next/error/complete)以及部分 Operators(RxJS:我直接好家伙),同樣支持高階 Observable,在被訂閱時(shí)才會(huì)開始推送數(shù)據(jù)(Lazy-Data-Emitting)。

          function listen(element, eventName{
            return new Observable((observer) => {
              // Create an event handler which sends data to the sink
              let handler = (event) => observer.next(event);

              // Attach the event handler
              element.addEventListener(eventName, handler, true);

              // Return a cleanup function which will cancel the event stream
              return () => {
                // Detach the event handler from the element
                element.removeEventListener(eventName, handler, true);
              };
            });
          }

          估計(jì)是因?yàn)檫€在 stage1 的關(guān)系,目前支持的操作符只有 of、from,但按照這個(gè)趨勢(shì)下去 RxJS 中的大部分操作符都會(huì)被吸收過來。

          個(gè)人感想:感覺需要非常久的時(shí)間才能看到未來結(jié)果,因?yàn)?RxJS 自身強(qiáng)大的多,海量操作符如果要吸收過來可能會(huì)是吃力不討好的。同時(shí),RxJS 的學(xué)習(xí)成本還是有的,我不認(rèn)為大家會(huì)因?yàn)樗晃盏?JS 語言原生就會(huì)紛紛開始學(xué)習(xí)相關(guān)概念。

          Promise.try (stage 1)

          proposal-promise-try[39]提案引入了Promise.try方法,這一方法其實(shí)很早就在bluebird[40]中提供了,其使用方式如下:

          function getUserNameById(id{
            return Promise.try(function ({
              if (typeof id !== "number") {
                throw new Error("id must be a number");
              }
              return db.getUserById(id);
            }).then((user) => {
              return user.name;
            });
          }

          Promise.try方法返回一個(gè) promise 實(shí)例,如果方法內(nèi)部拋出了錯(cuò)誤,則會(huì)走到.catch方法。上面的例子如果正常來寫,通常會(huì)這么寫:

          function getUserNameById(id{
            return db.getUserById(id).then(function (user{
              return user.name;
            });
          }

          看起來好像沒什么區(qū)別,但仔細(xì)想想,假設(shè)下面一個(gè)例子中,id 是錯(cuò)誤的,

          db.getUserById(id)返回了空值,那么這樣 user.name 無法獲取,將會(huì)走.catch,但如果不返回空值而是拋出一個(gè)同步錯(cuò)誤?Promises 的錯(cuò)誤捕獲功能的工作原理是所有同步代碼都位于.then 中,這樣它就可以將其包裝在一個(gè)巨大的try/catch塊中(所以同步錯(cuò)誤都能走到.catch中)。但是在這個(gè)例子中,db.getUserById(id)并非位于.then語句中,這就導(dǎo)致了這里的同步錯(cuò)誤無法被捕獲。簡(jiǎn)單的說,如果僅使用.then,只有第一次異步操作后的同步錯(cuò)誤會(huì)被捕獲。

          而是用Promise.try,它將捕獲db.getUserById(id)中的同步錯(cuò)誤(就像.then一樣,區(qū)別主要在 try 不需要前面跟著一個(gè) promise 實(shí)例),這樣子所有同步錯(cuò)誤就都能被捕獲了。

          Do Expression (stage 1)

          proposal-do-expressions[41]這個(gè)提案和throw Expressions 一樣,都是面向表達(dá)式(Expression-Oriented)的語法,函數(shù)式編程的重要優(yōu)勢(shì)之一。

          看看示例代碼:

          let x = do {
            let tmp = f();
            tmp * tmp + 1;
          };

          let y = do {
            if (foo()) {
              f();
            } else if (bar()) {
              g();
            } else {
              h();
            }
          };

          對(duì)于像我一樣沒接觸過函數(shù)式編程的同學(xué),這種語法可能確實(shí)很新奇有趣,而且對(duì)能幫助更好的組織代碼。這一提案還存在著一些注意點(diǎn):

          • do {}中不能僅有聲明語句,或者是缺少 else 的 if,以及循環(huán)。
          • 空白的do {}語句效果等同于void 0
          • await/yield標(biāo)識(shí)繼承自上下文

          對(duì)于異步版本的do expression,存在一個(gè)尚未進(jìn)入的提案proposal-async-do-expressions[42],旨在使用async do {}的語法,如:

          // at the top level of a script

          (async do {
            await readFile("in.txt");
            let query = await ask("???");
            // etc
          });

          Pipeline Operator (stage 1)

          目前 star 最多的提案,似乎沒有之一?

          proposal-pipeline-operator[43]提案引入了新的操作符|>,目前對(duì)于具體實(shí)現(xiàn)細(xì)節(jié)存在兩個(gè)不同的競(jìng)爭(zhēng)提案[44]。這一語法糖的主要目的是大大提升函數(shù)調(diào)用的可讀性,如doubleNumber(number)會(huì)變?yōu)?code style="font-size: 14.4px;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;padding: 3px 5px;border-radius: 2px;margin-right: 2px;margin-left: 2px;color: rgb(255, 53, 2);background: rgb(248, 245, 236);word-break: break-all;line-height: 1.5;">number |> doubleNumber的形式,對(duì)于鏈?zhǔn)降倪B續(xù)函數(shù)調(diào)用更是有奇效,如:

          function doubleSay(str{
            return str + ", " + str;
          }
          function capitalize(str{
            return str[0].toUpperCase() + str.substring(1);
          }
          function exclaim(str{
            return str + "!";
          }

          在管道操作符下,變?yōu)槿缦滦问剑?/p>

          let result = exclaim(capitalize(doubleSay("hello")));
          result; //=> "Hello, hello!"

          let result = "hello" |> doubleSay |> capitalize |> exclaim;

          result; //=> "Hello, hello!"

          確實(shí)大大提高了不少可讀性對(duì)吧?你可能會(huì)想,上面都是單個(gè)入?yún)ⅲ嵌鄠€(gè)呢,如下圖示例:

          function double(x{
            return x + x;
          }
          function add(x, y{
            return x + y;
          }

          function boundScore(min, max, score{
            return Math.max(min, Math.min(max, score));
          }

          let person = { score25 };

          let newScore =
            person.score
            |> double
            |> ((_) => add(7, _))
            |> ((_) => boundScore(0100, _));

          newScore; //=> 57

          等同于

          let newScore = boundScore(0100, add(7, double(person.score)));

          _ 只是形參名稱,你可以使用任意的形參名稱。

          Partial Application Syntax(stage 1)

          proposal-partial-application[45]這一提案引入了新的柯里化(也屬于柯里化吧,如果你看了下面的例子覺得不屬于,請(qǐng)不要揍我)方式,即原本我們使用 bind 方法來預(yù)先固定一個(gè)函數(shù)的部分參數(shù),得到一個(gè)高階函數(shù):

          function add(x, y{
            return x + y;
          }

          const addOne = add.bind(null1);
          addOne(2); // 3

          const addTen = (x) => add(x, 10);
          addTen(2); // 12

          使用 Partial Application Syntax,寫法會(huì)是這樣的:

          const addOne = add(1, ?);
          addOne(2); // 3

          const addTen = add(?, 10);
          addTen(2); // 12

          我們上一個(gè)列舉的提案proposal-pipeline-operator[46],其實(shí)可以在 Partial Application Syntax 的幫助下變得更加便捷,尤其是在多參數(shù)情況下:

          let person = { score25 };

          let newScore = person.score |> double |> add(7, ?) |> boundScore(0100, ?);
          • 目前的實(shí)現(xiàn)暫時(shí)不支持 await
          • 關(guān)于更多細(xì)節(jié),參考 Pipeline operator: Seeking champions[47] 以及 Pipeline operator draft[48]

          await.opts (stage 1)

          proposal-await.ops[49]這一提案為 await 引入了await.all/race/allSettled/any四個(gè)方法,來簡(jiǎn)化 Promise 的使用。實(shí)際上它們也正是Promise.all/race/allSettled/any的替代者,如:

          // before
          await Promise.all(users.map(async x => fetchProfile(x.id)))

          // after
          await.all users.map(async x => fetchProfile(x.id))

          Array Unique (stage 1)

          proposal-array-unique[50]主要是為了解決數(shù)組去重的問題,我們以往使用的[...new Set(array)] 無法很好的處理非原始類型的值,這一提案引入了Array.prototype.uniqueBy()方法來進(jìn)行數(shù)組的去重,類似于Lodash.uniqBy[51]

          個(gè)人感想:新的面試題出現(xiàn)了,請(qǐng)實(shí)現(xiàn)Array.prototype.uniqueBy()。2333,但是這個(gè)方法能原生支持還是很棒的。

          [1]

          JavaScript20 年-創(chuàng)立標(biāo)準(zhǔn): https://cn.history.js.org/part-2.html

          [2]

          ECMA(European Computer Manufacturers Association,歐洲計(jì)算機(jī)制造商協(xié)會(huì)): https://www.ecma-international.org/

          [3]

          2020 年 6 月發(fā)布的第 11 版: https://www.ecma-international.org/publications-and-standards/standards/ecma-262/

          [4]

          2015 年發(fā)布的 ES6: https://262.ecma-international.org/6.0/index.html

          [5]

          TC39 的 ECMA262 官網(wǎng): https://tc39.es/ecma262/

          [6]

          ECMA-414: https://www.ecma-international.org/publications-and-standards/standards/ecma-414/

          [7]

          ECMA-404: https://www.ecma-international.org/publications-and-standards/standards/ecma-404/

          [8]

          ECMA267: https://www.ecma-international.org/publications-and-standards/standards/ecma-267/

          [9]

          The TC39 process for ECMAScript features: https://2ality.com/2015/11/tc39-process.html

          [10]

          proposal-record-tuple: https://github.com/tc39/proposal-record-tuple

          [11]

          proposal-relative-indexing-method: https://github.com/tc39/proposal-relative-indexing-method

          [12]

          proposal-array-last: https://github.com/tc39/proposal-array-last

          [13]

          proposal-array-find-from-last: https://github.com/tc39/proposal-array-find-from-last

          [14]

          proposal-temporal: https://github.com/tc39/proposal-temporal

          [15]

          ts39-proposal-temporal docs: https://tc39.es/proposal-temporal/docs/index.html

          [16]

          private-methods: https://github.com/tc39/proposal-private-methods

          [17]

          ES6 標(biāo)準(zhǔn)入門: https://es6.ruanyifeng.com/#docs/class#%E7%A7%81%E6%9C%89%E5%B1%9E%E6%80%A7%E7%9A%84%E6%8F%90%E6%A1%88

          [18]

          proposal-class-fields: https://github.com/tc39/proposal-class-fields

          [19]

          proposal-top-level-await: https://github.com/tc39/proposal-top-level-await

          [20]

          proposal-import-assertions: https://github.com/tc39/proposal-import-assertions

          [21]

          proposal-json-modules: https://github.com/tc39/proposal-json-modules

          [22]

          proposal-error-cause: https://github.com/tc39/proposal-error-cause

          [23]

          吞吞老師: https://github.com/legendecas

          [24]

          proposal-decorators: https://github.com/tc39/proposal-decorators

          [25]

          stage 2: https://github.com/tc39/proposal-decorators

          [26]

          Optional chaining: https://github.com/tc39/proposal-optional-chaining

          [27]

          Nullish-Coalescing: https://github.com/tc39/proposal-nullish-coalescing

          [28]

          AtScript: https://github.com/angular/atscript-playground

          [29]

          是否應(yīng)該在 production 里使用 typescript 的 decorator?: https://www.zhihu.com/question/404724504

          [30]

          proposal-iterator-helpers: https://github.com/tc39/proposal-iterator-helpers

          [31]

          Itertools: https://www.npmjs.com/package/itertools

          [32]

          itertools: https://docs.python.org/library/itertools.html

          [33]

          Prior Art: https://github.com/tc39/proposal-iterator-helpers#prior-art

          [34]

          rxjs-for-await: https://github.com/benlesh/rxjs-for-await

          [35]

          proposal-throw-expressions: https://github.com/tc39/proposal-throw-expressions

          [36]

          proposal-set-methods: https://github.com/tc39/proposal-set-methods

          [37]

          proposal-upsert: https://github.com/tc39/proposal-upsert

          [38]

          proposal-observable: https://github.com/tc39/proposal-observable

          [39]

          proposal-promise-try: https://github.com/tc39/proposal-promise-try

          [40]

          bluebird: http://bluebirdjs.com/docs/api/promise.try.html

          [41]

          proposal-do-expressions: https://github.com/tc39/proposal-do-expressions

          [42]

          proposal-async-do-expressions: https://github.com/tc39/proposal-async-do-expressions

          [43]

          proposal-pipeline-operator: https://github.com/tc39/proposal-pipeline-operator

          [44]

          兩個(gè)不同的競(jìng)爭(zhēng)提案: https://github.com/tc39/proposal-pipeline-operator/wiki

          [45]

          proposal-partial-application: https://github.com/tc39/proposal-partial-application

          [46]

          proposal-pipeline-operator: https://github.com/tc39/proposal-pipeline-operator

          [47]

          Pipeline operator: Seeking champions: https://docs.google.com/presentation/d/1for4EIeuVpYUxnmwIwUuAmHhZAYOOVwlcKXAnZxhh4Q/edit#slide=id.g79e9b7164e_0_531

          [48]

          Pipeline operator draft: https://tc39.es/proposal-pipeline-operator/

          [49]

          proposal-await.ops: https://github.com/tc39/proposal-await.ops

          [50]

          proposal-array-unique: https://github.com/tc39/proposal-array-unique

          [51]

          ...new Set(array)]無法很好的處理非原始類型的值,這一提案引入了Array.prototype.uniqueBy()`方法來進(jìn)行數(shù)組的去重,類似于[Lodash.uniqBy: https://www.lodashjs.com/docs/lodash.uniqBy

          最后



          如果你覺得這篇內(nèi)容對(duì)你挺有啟發(fā),我想邀請(qǐng)你幫我三個(gè)小忙:

          1. 點(diǎn)個(gè)「在看」,讓更多的人也能看到這篇內(nèi)容(喜歡不點(diǎn)在看,都是耍流氓 -_-)

          2. 歡迎加我微信「 sherlocked_93 」拉你進(jìn)技術(shù)群,長期交流學(xué)習(xí)...

          3. 關(guān)注公眾號(hào)「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時(shí)聊騷。


          點(diǎn)個(gè)在看支持我吧,轉(zhuǎn)發(fā)就更好了


          瀏覽 46
          點(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>
                  影音先锋 麻豆 | 成人A片网 | a线视频免费观看:中文字幕 | 大鸡吧一区 | 伊人日产无码中文久久久 |