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

          2021年,快速了解 ES2022 新特性(二)

          共 10627字,需瀏覽 22分鐘

           ·

          2021-12-28 21:05

          大廠技術(shù)??高級(jí)前端??Node進(jìn)階

          點(diǎn)擊上方?程序員成長(zhǎng)指北,關(guān)注公眾號(hào)

          回復(fù)1,加入高級(jí)Node交流群



          接著上一篇快速了解ES特性之一(ES7-ES8)[3] ,今天我們主要來(lái)講ES新特性之 ES9 。上篇中我們已經(jīng)講了ES的由來(lái),版本對(duì)應(yīng)規(guī)則等等內(nèi)容,這里我就不再贅述。讓我們直接開(kāi)始吧

          快速了解ES特性 是我的系列文章,現(xiàn)在已有

          1. 快速了解ES特性之一(ES7-ES8)[4]
          2. 快速了解ES特性之二(ES9)[5]

          ES2018 / ES9

          Lifting template literal restriction 提升模板文字限制

          字符串模板語(yǔ)法是 ES6 的特性(很不巧的是,我根據(jù) 已完成的ES提案[6] 這里來(lái)講的,所以沒(méi)有寫(xiě) ES6 相關(guān)的內(nèi)容,后面會(huì)寫(xiě)一個(gè)來(lái)補(bǔ)充)。在 ES6 的版本中,我們不能在帶標(biāo)簽的模板字符串中插入像 \unicode 之類的 錯(cuò)誤 轉(zhuǎn)義字符,如果使用這類錯(cuò)誤的轉(zhuǎn)義字符導(dǎo)致 bad escape sequence: \unicode 的錯(cuò)誤。在 ES9 中則放開(kāi)了這些限制,讓這些錯(cuò)誤的轉(zhuǎn)義也可以正確的執(zhí)行。下面我們舉例說(shuō)明一下

          function?hi(strings)?{
          ??console.log(strings);
          }
          let?words?=?hi`hi,?\ustar;`;
          復(fù)制代碼

          這里的 \ustar 很明顯不是一個(gè)正確的 Unicode ,我們這里使用 es-check[7] 指定 es6 來(lái)檢驗(yàn)一下是否正確

          es-check?es6?test.js
          //?SyntaxError:?Bad?character?escape?sequence?(4:21)
          復(fù)制代碼

          很明顯和我們上文中說(shuō)的錯(cuò)誤一樣,無(wú)法正確識(shí)別轉(zhuǎn)義字符。我們這次將 es-check[8] 版本指定為 es9 ,再次檢測(cè),no errors!

          es-check?es9?test.js
          //?ES-Check:?there?were?no?ES?version?matching?errors!
          復(fù)制代碼

          類似的像 \x 打頭的非十六進(jìn)制、 \123 這種錯(cuò)誤的轉(zhuǎn)義,現(xiàn)在在 ES9 中都是 ok 的。

          s (dotAll) flag for regular expressions

          在正則表達(dá)式模式中,我們可以使用點(diǎn) . 匹配任意的單個(gè)字符。但是這里面卻有兩個(gè)例外,默認(rèn):

          • . 不匹配 星體字符
          • . 不匹配 行終止符

          默認(rèn)不匹配 星體字符,我們可以通過(guò)給正則設(shè)置 u (unicode) 這個(gè)標(biāo)志來(lái)解決這個(gè)問(wèn)題。但是對(duì)于 行終止符 來(lái)說(shuō),卻沒(méi)有一個(gè)類似的 flag 來(lái)解決這個(gè)問(wèn)題。按照正常的正則語(yǔ)義,點(diǎn) . 可以匹配任意字符,但實(shí)際上只能識(shí)別下面列出的 行終止符

          • U+000A 換行 (LF) (\n)
          • U+000D 回車(chē) (CR) (\r)
          • U+2028 線分隔符
          • U+2029 段落分隔符

          在實(shí)際的場(chǎng)景中,還有一些字符可以被認(rèn)為是 行終止符 ,比如說(shuō):

          • U+000B 垂直制表符 (\v)
          • U+000C 換頁(yè) (\f)
          • U+0085 下一行

          java 中,我們可以指定 flag Pattern.DOTALL 來(lái)讓 . 匹配所有;在 C# 則用 RegexOptions.Singleline 來(lái)匹配所有。所以 es9 新增了一個(gè) flag s,來(lái)補(bǔ)充上面的場(chǎng)景。下面我們舉例來(lái)說(shuō)明一下

          const?str?=?`
          hello
          world
          `
          ;
          const?r1?=?/hello.world/;
          console.log(r1.test(str),?r1.dotAll,?r1.flags);
          //?false?false
          const?r2?=?/hello.world/s;?//?添加?'s'?flag
          console.log(r2.test(str),?r2.dotAll,?r2.flags);
          //?true?true?s
          復(fù)制代碼

          有的同學(xué)可能會(huì)有這樣的疑問(wèn),這里為啥叫 ss 代表的 singleline 不會(huì)和 m ( multiline ) 沖突嗎 ?用官方的話來(lái)說(shuō):s 代表就是 singleline,也是 dotAll,含義一致。我們不好意思加一個(gè)新的標(biāo)記來(lái)做這件事情。s ( dotAll )表示的是讓 . 可以匹配任意字符,和 m ( multiline ) 標(biāo)記不沖突。大家愛(ài)咋用就咋用 ??

          RegExp named capture groups 正則命名捕獲組

          這個(gè)特性就比較花哨了,在以往的代碼中,假如我們要匹配一個(gè)日期中的年月日,我們可能是這樣做的

          const?str?=?"2021-10-24";
          const?r1?=?/(\d{4})-(\d{2})-(\d{2})/;
          const?groups?=?r1.exec(str);
          console.log("year:",?groups[1],?"month:",?groups[2],?"day:",?groups[3]);
          //?year:?2021?month:?10?day:?24
          復(fù)制代碼

          沒(méi)毛病啊,老鐵 ??,我所知道的幾門(mén)語(yǔ)言都是這樣做的。在這個(gè)語(yǔ)法出來(lái)之前,我都沒(méi)有思考過(guò)直接用上面的語(yǔ)法寫(xiě)有啥毛病。按照定式思維,大家都這樣做,那這樣做就是對(duì)的。但是這個(gè)用官方的話來(lái)說(shuō):我們?nèi)绻闯R?guī)的寫(xiě)法來(lái)寫(xiě)正則,我們?cè)谑褂眠@個(gè) groups 的時(shí)候,假如我要獲取 月份 這個(gè)值,那么就需要仔細(xì)看一下這個(gè)正則表達(dá)式,我們用 括號(hào) 包的月份這個(gè)值,數(shù)一下,在第二個(gè),按照正則的規(guī)則,groups 的第 0 個(gè)是表達(dá)式匹配的整串,要獲取后面分組出來(lái)的值需要 +1 ,所以我們要獲取 月份 這個(gè)值的索引應(yīng)該是 2 ,最終結(jié)果:groups[2] 。是不是很麻煩,還很容易錯(cuò)?我:黑人問(wèn)號(hào).jpg。要這么說(shuō)也沒(méi)毛病,現(xiàn)在我們來(lái)看看這個(gè)規(guī)范是怎么樣的:在先前分組的內(nèi)容前面加上一個(gè) ?<給分組取的別名>,整的在一起就是 (?<給分組取的別名>...) 。我們把上面的示例修改一下

          const?str?=?"2021-10-24";
          const?r1?=?/(?\d{4})-(?\d{2})-(?\d{2})/;
          const?exec?=?r1.exec(str);
          console.log("year:",?exec[1],?"month:",?exec[2],?"day:",?exec[3]);
          console.log("year:",?exec.groups.year,?"month:",?exec.groups.month,?"day:",?exec.groups.day);
          //?const?{?groups:?{?year,?month,?day?}?}?=?exec;
          //?console.log("year:",?year,?"month:",?month,?"day:",?day);
          //?year:?2021?month:?10?day:?24
          //?year:?2021?month:?10?day:?24
          復(fù)制代碼

          是不是花哨起來(lái)了?no,no,no。這并不是全部,我們還可以進(jìn)行更花哨的匹配。如果我們需要匹配一個(gè)復(fù)雜重復(fù)字符串,比如我們需要匹配一個(gè)文本是否包含 aaabbbccc任何字符aaabbbccc任何字符aaabbbccc ,常規(guī)的寫(xiě)法如下

          const?str?=?'asjdhkjlhsdkjaaabbbcccahsdkjashdjhsaaaabbbcccasjhdkljdhjkdaaaabbbcccashdlkj';
          const?r1?=?/a{3,}b{3}c{3,}.+a{3,}b{3}c{3,}.+a{3,}b{3}c{3,}/;
          const?result?=?r1.test(str);
          console.log(result);
          //?true
          復(fù)制代碼

          是不是感覺(jué)上面的正則有些繁瑣呢?這里我們可以使用這個(gè)命名捕獲進(jìn)行更加花哨的使用,這也是命名捕獲的一個(gè)新特性,如果我們需要匹配一個(gè)和前某個(gè)表達(dá)式一樣的結(jié)果,我們可以在表達(dá)式中用 \k 來(lái)替換,而不是重新寫(xiě)一次一樣的表達(dá)式

          const?str?=?'asjdhkjlhsdkjaaabbbcccahsdkjashdjhsaaaabbbcccasjhdkljdhjkdaaaabbbcccashdlkj';
          const?r1?=?/(?a{3,}b{3}c{3,}).+\k.+\k/;
          const?result?=?r1.test(str);
          console.log(result);
          //?true
          復(fù)制代碼

          現(xiàn)在看起來(lái)是不是要好很多呢?上面的例子比較簡(jiǎn)單,如果遇上更加復(fù)雜的情況,這個(gè)特性可以幫我們少寫(xiě)很多重復(fù)的規(guī)則,并且更加的準(zhǔn)確,減少出錯(cuò)的概率。

          這個(gè)命名捕獲同樣適用于字符串替換,我們還是用上面的日期做示例吧。假如我們需要把一個(gè)日期從 yyyy-MM-dd 變成 dd/MM/yyyy ,傳統(tǒng)的寫(xiě)法是

          const?str?=?"2021-10-24";
          const?r1?=?/(\d{4})-(\d{2})-(\d{2})/;
          const?rd?=?str.replace(r1,"$3/$2/$1");
          console.log(rd);
          //?24/10/2021
          復(fù)制代碼

          我們修改成命名捕獲

          const?str?=?"2021-10-24";
          const?r1?=?/(?\d{4})-(?\d{2})-(?\d{2})/;
          const?rd?=?str.replace(r1,"$/$/$");
          console.log(rd);
          //?24/10/2021
          復(fù)制代碼

          確實(shí)更加快速確準(zhǔn),且不易出錯(cuò)

          Rest/Spread Properties

          ES6 中我們已經(jīng)有了對(duì)數(shù)組的解構(gòu)賦值的剩余元素和數(shù)組字符串的展開(kāi)方法。在 ES9 中則增加了對(duì)象的解構(gòu)賦值剩余屬性和對(duì)象字面量的展開(kāi)。這個(gè)沒(méi)有啥多說(shuō)的,直接舉例吧

          const?obj?=?{
          ??x:?1,?y:?2,?z:?3,?a:?"x",?b:?"y",?c:?"z",
          };
          const?{?x,?y,?z,?...letter?}?=?obj;
          console.log(x,?y,?z,?letter);
          //?1?2?3?{?a:?'x',?b:?'y',?c:?'z'?}
          復(fù)制代碼

          這個(gè) Rest Properties ,我不知道用那個(gè)詞來(lái)準(zhǔn)確描述它,但是用起來(lái)卻是很順手。就如上面例子中的,我們從對(duì)象中解出 x, y, z ,并用 ... 這個(gè)展開(kāi)符,將剩下的 a, b, c 重新組合到了新的對(duì)象 letter 中,原始的 obj 被吃光抹盡,所有都被提取出來(lái)了。所以 Rest Properties 就是讓 x, y, z 出來(lái)接客,讓剩下的 a, b, cletter 中休息?????

          我們接著講展開(kāi),使用上面的例子

          //?...
          const?objClone?=?{
          ??x,?y,?z,?...letter,
          };
          console.log(objClone);
          //?{?x:?1,?y:?2,?z:?3,?a:?'x',?b:?'y',?c:?'z'?}
          復(fù)制代碼

          這里展開(kāi)符就和其義一毛一樣了,我們把 letter 里面的 a, b, c ,展開(kāi)成一個(gè)個(gè)的屬性復(fù)制給 objClone 。這里就沒(méi)有什么理解偏差,展開(kāi)符嘛,不就是把這些元素啊,屬性啊,拿出來(lái)給新的對(duì)象嗎?

          RegExp Lookbehind Assertions 正則表達(dá)式回溯斷言

          ES9 之前 EMACScript 正則只支持先行斷言,到了 ES9 正式支持后行斷言。這里我不多做展開(kāi)講,因?yàn)檫@個(gè)不涉及特殊的語(yǔ)法,后面我會(huì)單獨(dú)寫(xiě)一篇文章來(lái)講解 正則表達(dá)式 ,各語(yǔ)言基本通用,一把梭哈。

          下面我就簡(jiǎn)簡(jiǎn)單單舉個(gè)例子:假如我們需要匹配一個(gè)字符串 xyz 只有當(dāng)它前面是 uvw 時(shí)才匹配

          在沒(méi)有后行斷言的時(shí)候,如果要匹配,我們一般要這樣寫(xiě)

          const?str?=?"rstuvwxyz123";
          const?r?=?/uvw(xyz)/;
          const?result?=?r.exec(str);
          console.log(result);
          //?[?'uvwxyz',?'xyz',?index:?3,?input:?'rstuvwxyz123',?groups:?undefined?]
          復(fù)制代碼

          有了后行斷言之后

          const?str?=?"rstuvwxyz123";
          const?r?=?/(?<=uvw)xyz/;
          const?result?=?r.exec(str);
          console.log(result);
          //?[?'xyz',?index:?6,?input:?'rstuvwxyz123',?groups:?undefined?]
          復(fù)制代碼

          有的同學(xué)肯定就疑惑了?上面那種不是更簡(jiǎn)單嗎 ?? 。我覺(jué)得有道理,所以我把結(jié)果打印了一手。如果我們僅僅判斷一下是否匹配,確實(shí)用第一種方式,如果我們需要匹配結(jié)果,這兩種寫(xiě)法就有了區(qū)別。如果使用后行斷言,uvw 是不會(huì)出現(xiàn)在匹配結(jié)果中的。

          上面我們講的僅僅只是后行斷言的 正面斷言 ,還有與之相反的 負(fù)面斷言(反向否定查找) 。我們接著使用上面的例子,但是這次我們需要的是 xyz 前面不是 uvw 時(shí)才匹配

          const?str?=?"rstuvwxyz123";
          const?r?=?/(?;
          const?result?=?r.exec(str);
          console.log(result);
          //?null
          復(fù)制代碼

          現(xiàn)在 xyz 前面緊挨著 uvw ,所以啥都匹配不到,我們修改一下,在 uvw 中間插入一個(gè) 0

          const?str?=?"rstuv0wxyz123";
          const?r?=?/(?;
          const?result?=?r.exec(str);
          console.log(result);
          //?[?'xyz',?index:?7,?input:?'rstuv0wxyz123',?groups:?undefined?]
          復(fù)制代碼

          現(xiàn)在就我們可以匹配到了

          RegExp Unicode Property Escapes 正則表達(dá)式中的 Unicode 屬性轉(zhuǎn)義

          我們?cè)谑褂谜齽t表達(dá)式的時(shí)候,常常需要匹配出不同的語(yǔ)言文字特殊符號(hào)等。比如說(shuō)我們常見(jiàn)的需求:某個(gè)表單中不能夠輸入 emoji 或者其他的特殊字符,一丟丟的其他語(yǔ)種啊之類的,按照先前的寫(xiě)法,我們常常得引入三方庫(kù)來(lái)匹配這些 奇怪的字符 ,但是這些 奇怪的字符 的范圍一直在不停的變化,所以我們引入的這些庫(kù)就存在需要經(jīng)常更新的問(wèn)題。比如 emoji 就是更新狂魔,要匹配 emoji 就不得不不斷更新 emoji 匹配庫(kù)才能正確的過(guò)濾掉它們。現(xiàn)在我們只需要這樣

          const?str?=?"hi,???";
          const?r1?=?/\p{Emoji}/gu;
          console.log(r1.exec(str));
          //?['??',?index:?4,?input:?'hi,???',?groups:?undefined]
          復(fù)制代碼

          就可以輕易的匹配到 emoji 表情,???有的同學(xué)可能直接就黑人問(wèn)號(hào).jpg了,對(duì)的,你沒(méi)有看錯(cuò),只需要這樣你就可以匹配到 emoji 了,這里也涉及了一丟丟 Unicode Emoji 的東西,想了解詳情的同學(xué),可以在 這兒[9] 查看到詳情和更多類似花括號(hào)包裹的 Emoji 這樣的東西,比如更常用的 Emoji_Presentation

          如果我想要匹配不是 Emoji 的呢?我們只需要把小 p 換成大 P 即可,是不是很簡(jiǎn)單呢?

          const?str?=?"hi,???";
          const?r2?=?/(\P{Emoji})*/gu;
          console.log(r2.exec(str));
          //?['hi,?',?'?',?index:?0,?input:?'hi,???',?groups:?undefined]
          復(fù)制代碼

          這個(gè)特性很強(qiáng),但是建議先不急著用,em em em,畢竟也得看瀏覽器嘛。當(dāng)然這個(gè)特性也不止這點(diǎn)東西,想要了解更多這個(gè)特性的同學(xué),可以到這兒 MDN \- Unicode property escapes[10] 仔細(xì)研讀,我也不多講了,大家加油

          Promise.prototype.finally

          這個(gè)就真的沒(méi)啥講頭了咯,這個(gè)方法是在 Promise then 或者 catch 執(zhí)行完之后執(zhí)行。一般就用來(lái)修改加載狀態(tài)或者某種用完就需要關(guān)閉的資源,比如:

          this.loading?=?true;
          xxxApi
          ??.listUser()
          ??.then((resp)?=>?{
          ????//?do?something...
          ??})
          ??.catch((e)?=>?{
          ????//?do?something...
          ??})
          ??.finally(()?=>?{
          ????this.loading?=?false;
          ??});
          復(fù)制代碼

          不單單只是上面說(shuō)的兩種場(chǎng)景,如果我們需要在任務(wù)執(zhí)行完做某件事的時(shí)候,都可以用這個(gè)方法實(shí)現(xiàn)。

          Asynchronous Iteration 異步迭代器

          ES9 中,新增了 for-await-of 的用法。對(duì)于同步的迭代器,假如我們有一個(gè) Promise 數(shù)組,要等著 Promise 元素一個(gè)個(gè)執(zhí)行完,如果按我們之前的方式

          function?newPromise(delay)?{
          ??return?new?Promise((resolve)?=>?{
          ????setTimeout(()?=>?{
          ??????console.log(`resolve:`,?delay);
          ??????resolve(delay);
          ????},?delay);
          ??});
          }

          async?function?test()?{
          ??const?arr?=?[newPromise(3000),?newPromise(2000),?newPromise(4000)];
          ??const?before?=?Date.now();
          ??for?(const?item?of?arr)?{
          ????console.log(Date.now(),?await?newPromise(1234));
          ????console.log(Date.now(),?await?item);
          ??}
          ??console.log(Date.now()?-?before);
          }
          test();
          //?resolve:?1234
          //?1635088618117?1234
          //?resolve:?2000
          //?resolve:?3000
          //?1635088619374?3000
          //?resolve:?4000
          //?resolve:?1234
          //?1635088621117?1234
          //?1635088622369?2000
          //?resolve:?1234
          //?1635088622369?1234
          //?1635088623616?4000
          //?5500
          復(fù)制代碼

          如果我們換成 for-await-of

          async?function?test2()?{
          ??const?arr?=?[newPromise(3000),?newPromise(2000),?newPromise(4000)];
          ??const?before?=?Date.now();
          ??for?await?(const?item?of?arr)?{
          ????console.log(Date.now(),?await?newPromise(1234));
          ????console.log(Date.now(),?item);
          ??}
          ??console.log(Date.now()?-?before);
          }
          test2();
          //?resolve:?2000
          //?resolve:?3000
          //?resolve:?4000
          //?resolve:?1234
          //?1635088545345?1234
          //?1635088546584?3000
          //?resolve:?1234
          //?1635088546584?1234
          //?1635088547826?2000
          //?resolve:?1234
          //?1635088547826?1234
          //?1635088549066?4000
          //?6733
          復(fù)制代碼

          如果就單單看結(jié)果而言,基本沒(méi)差,最終結(jié)果都一樣。但實(shí)際的執(zhí)行方式還是有差別:

          • 直接在循環(huán)中 await 的方式,是每一個(gè)獨(dú)立的 Promise 的等待,在第一個(gè)的打印中我們可以看出來(lái),所有的任務(wù)根據(jù) delay 的時(shí)長(zhǎng),依次 resolve
          • 使用 for-await-of 會(huì)將數(shù)組的統(tǒng)一處理,然后再執(zhí)行循環(huán)體內(nèi)的代碼。

          說(shuō)到底還是往事件循環(huán)里推事件的時(shí)機(jī)不同,實(shí)際業(yè)務(wù)場(chǎng)景中的使用,還得看各位同學(xué)的需求,不同的寫(xiě)法還是有差別的,別弄錯(cuò)了就成。

          說(shuō)完同步,現(xiàn)在我們來(lái)說(shuō)說(shuō) 異步迭代器 ,在 ES9 中新增了一個(gè) Symbol.asyncIterator[11]符號(hào)用來(lái)給對(duì)象自定義默認(rèn)的異步迭代器。

          下面我們舉個(gè)例子來(lái)創(chuàng)建一個(gè)異步可迭代對(duì)象

          const?ai?=?{
          ??//?整一個(gè)方法用來(lái)結(jié)束
          ??dispose()?{
          ????this.disposed?=?true;
          ??},
          ??[Symbol.asyncIterator]()?{
          ????return?{
          ??????//?下面的方法都用上箭頭函數(shù),免得手寫(xiě)that
          ??????next:?()?=>?{
          ????????return?new?Promise((resolve,?_)?=>?{
          ??????????setTimeout(()?=>?{
          ????????????resolve({
          ??????????????done:?!!this.disposed,
          ??????????????value:?Date.now(),
          ????????????});
          ??????????},?200);
          ????????});
          ??????},
          ????};
          ??},
          };

          async?function?test()?{
          ??for?await?(const?it?of?ai)?{
          ????console.log(it);
          ??}
          }

          test();
          setTimeout(()?=>?{
          ??ai.dispose();
          },?1000);?//?一秒后結(jié)束

          //?1635170851461
          //?1635170851679
          //?1635170851881
          //?1635170852084
          復(fù)制代碼

          上面的例子中,我們?cè)谝粋€(gè)對(duì)象中,聲明了一個(gè) Symbol.asyncIterator 的屬性方法,這個(gè)屬性方法返回一個(gè)對(duì)象,對(duì)象中包含一個(gè) next 方法。看起來(lái)是不是很熟悉?我們聲明一個(gè)同步迭代器,也是這樣做的。再看看這個(gè)方法的返回值,如果使用同步迭代器,我們直接返回 { value , done } 即可,value 表示實(shí)際的值,done 是個(gè)布爾值,用來(lái)標(biāo)記迭代器是否迭代完成。在異步迭代器中,我們返回的是一個(gè) Promise 對(duì)象,返回的內(nèi)容則是 Promise resolve({ value , done })valuedone 的含義和上述同步迭代器一致。

          有的同學(xué)可能想,這么寫(xiě)是不是太麻煩了,我們?cè)谕降髦锌梢赃@樣寫(xiě)

          const?iterator?=?{
          ??[Symbol.iterator]:?function*?()?{
          ????yield?`a`;
          ????yield?`b`;
          ????yield?`c`;
          ??},
          };
          for?(const?it?of?iterator)?{
          ??console.log(it);
          }
          //?a
          //?b
          //?c
          復(fù)制代碼

          那在異步迭代器中是不是也可以這樣寫(xiě)?答案當(dāng)然是肯定的咯,我們只需要在 function 前面加個(gè) async 用來(lái)表示是個(gè)異步迭代器即可

          const?asyncIterator?=?{
          ??[Symbol.asyncIterator]:?async?function*?()?{
          ????yield?`a`;
          ????yield?`b`;
          ????yield?`c`;
          ??},
          };

          (async?()?=>?{
          ??for?await?(const?x?of?asyncIterator)?{
          ????console.log(x);
          ??}
          })();
          //?a
          //?b
          //?c
          復(fù)制代碼

          看起來(lái)是不是 ojbk ?同樣

          function*?it()?{
          ??yield?`a`;
          ??yield?`b`;
          ??yield?`c`;
          }

          for?(const?i?of?it())?{
          ??console.log(i);
          }
          //?a
          //?b
          //?c
          async?function*?ait()?{
          ??yield?`a`;
          ??yield?`b`;
          ??yield?`c`;
          }

          (async?()?=>?{
          ??for?await?(const?i?of?ait())?{
          ????console.log(i);
          ??}
          })();
          //?a
          //?b
          //?c
          復(fù)制代碼

          這個(gè)看起來(lái)是不是感覺(jué)N多語(yǔ)言都有這個(gè)?看起來(lái)就是標(biāo)準(zhǔn)的 Stream 實(shí)現(xiàn),大家都大同小異,這樣也挺好,方便理解嘛,一個(gè)懂了,其他的基本也就ok了

          總結(jié)

          文章到這兒又要和大家說(shuō)再見(jiàn)了,寥寥幾個(gè)特性有的時(shí)候真的恨不得寫(xiě)個(gè)幾萬(wàn)字,因?yàn)樯婕暗臇|西實(shí)在是太多了,不是簡(jiǎn)單幾句就能說(shuō)明白的。但是呢,這個(gè)時(shí)間它不允許啊,我也就只能含淚和大家說(shuō)晚安了。

          這篇文章也寫(xiě)了我?guī)滋欤瑢?xiě)寫(xiě)這,寫(xiě)寫(xiě)那兒的,總算也是寫(xiě)完了。感覺(jué)這個(gè) ES9 全是正則相關(guān)的 ??,文章里面我給自己留了一個(gè)作業(yè),有空水一篇正則使用的文章。這個(gè)正則我相信很多同學(xué)都是迷迷糊糊的,我見(jiàn)過(guò)不少N年經(jīng)驗(yàn)的對(duì)正則也不甚了解。所以這個(gè)正則,我肯定是要水的,盡請(qǐng)期待一下吧,不說(shuō)包會(huì),至少能夠和別人吹吹牛皮。


          如果文章對(duì)您有幫助的話,歡迎 點(diǎn)贊評(píng)論關(guān)注收藏分享 ,您的支持是我碼字的動(dòng)力,萬(wàn)分感謝!!!??

          如果文章內(nèi)容出現(xiàn)錯(cuò)誤的地方,歡迎指正,交流,謝謝??

          最后,大家可以 點(diǎn)擊這兒[12] 加入QQ群 FlutterCandies??[13] 和各路大佬們進(jìn)行交流哦,這里大家說(shuō)話都超好聽(tīng)的


          關(guān)于本文

          來(lái)源:盡管如此世界依然美麗

          https://juejin.cn/post/7023037816204427272


          最后


          Node 社群


          我組建了一個(gè)氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對(duì)Node.js學(xué)習(xí)感興趣的話(后續(xù)有計(jì)劃也可以),我們可以一起進(jìn)行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。


          ???“分享、點(diǎn)贊在看” 支持一波??

          瀏覽 24
          點(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>
                  一二三区视频 | 男人爱天堂资源网 | 操操操免费视频 | 夫妻自拍在线视频 | 国产精品自产拍高潮在线观看 |