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

          共 13585字,需瀏覽 28分鐘

           ·

          2021-10-18 11:53

          推薦關(guān)注↓

          前言

          最近看到了一些很有趣的 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)的競爭落得下風(fēng),為了避免最終 Web 腳本主導(dǎo)權(quán)落入微軟手中,網(wǎng)景開始尋求 ECMA 組織的幫助,來推動(dòng) JavaScript 的標(biāo)準(zhǔn)化。

          • 在 1996 年,JavaScript 正式加入了 ECMA 大家庭,我們后面會(huì)叫它 ECMAScript(下文簡稱 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?=?#{
          ??id:?1234,
          ??title:?"Record?&?Tuple?proposal",
          ??contents:?`...`,
          ??keywords:?#["ecma",?"tc39",?"proposal",?"record",?"tuple"],
          };

          //?Tuple
          const?measures?=?#[42,?12,?67,?"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({?year:?2006,?month:?8,?day:?24?});?//?=>?2006-08-24
          date.year;?//?=>?2006
          date.inLeapYear;?//?=>?false
          date.toString();?//?=>?'2006-08-24'
          • Temporal.PlainTime 獲取 wall-clock time(和上面一樣,不知道咋翻譯):
          const?time?=?Temporal.PlainTime.from({
          ??hour:?19,
          ??minute:?39,
          ??second:?9,
          ??millisecond:?68,
          ??microsecond:?346,
          ??nanosecond:?205,
          });?//?=>?19:39:09.068346205

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

          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)用上了。簡單地說,就是你的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。這里引用我早前的一篇文章來簡單講述下裝飾器的歷史:

          首先我們需要知道,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](),而 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]。示例:

          function*?naturals()?{
          ??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ò)誤無法被捕獲。簡單的說,如果僅使用.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è)不同的競爭提案[44]。這一語法糖的主要目的是大大提升函數(shù)調(diào)用的可讀性,如doubleNumber(number)會(huì)變?yōu)?code style="font-size: 14px;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);">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?=?{?score:?25?};

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

          newScore;?//=>?57

          等同于

          let?newScore?=?boundScore(0,?100,?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(null,?1);
          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?=?{?score:?25?};

          let?newScore?=?person.score?|>?double?|>?add(7,??)?|>?boundScore(0,?100,??);
          • 目前的實(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è)方法,來簡化 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


          轉(zhuǎn)自:林不渡

          https://juejin.cn/post/6974330720994983950

          瀏覽 67
          點(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>
                  青草青青精品视频在线观看 | 国产精品无码一区二区三区免费 | 成人无码操屄AV大片 | 四虎无码 | 黄色视频链接在线观看 |