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

          2022年了,這些ES7-ES12的知識(shí)點(diǎn)你都掌握了嘛?

          共 19177字,需瀏覽 39分鐘

           ·

          2022-01-22 09:28

          點(diǎn)擊上方?前端瓶子君,關(guān)注公眾號(hào)

          回復(fù)算法,加入前端編程面試算法每日一題群

          前言

          聽說現(xiàn)在大家在工作中ES6語法都已經(jīng)用的爐火純青了,那ES7-ES12的新特性你現(xiàn)在都用上了嘛?很多的新特性在開發(fā)中還是很實(shí)用的,也解決了很多js存在的問題。自己熬夜爆肝一個(gè)周末,總結(jié)出了ES7-ES12的語法,希望對(duì)你能有一定的幫助。最后,了解真相,你才能獲得真正的自由!

          ES2016(ES7)

          Array.prototype.includes()

          includes()?方法用來判斷一個(gè)數(shù)組是否包含一個(gè)指定的值,如果包含則返回?true,否則返回?false。

          語法

          arr.includes(valueToFind[,?fromIndex])
          復(fù)制代碼

          valueToFind,需要查找的元素值。

          fromIndex?可選 從fromIndex?索引處開始查找?valueToFind。如果為負(fù)值(即從末尾開始往前跳?fromIndex?的絕對(duì)值個(gè)索引,然后往后搜尋)。默認(rèn)為 0。

          示例

          const?arr?=?['es6',?'es7',?'es8']
          console.log(arr.includes('es7'))?//?true
          console.log(arr.includes('es7',?1))?//?true
          console.log(arr.includes('es7',?2))?//?false
          console.log(arr.includes("es7",?-1));?//?fsle
          console.log(arr.includes("es7",?-2));?//?true
          復(fù)制代碼

          注意點(diǎn)

          使用 includes()查找字符串是區(qū)分大小寫的。

          const?arr?=?["es6",?"es7",?"es8",?"a"];
          console.log(arr.includes("A"));?//?false
          復(fù)制代碼

          使用 includes()只能判斷簡(jiǎn)單類型的數(shù)據(jù),對(duì)于復(fù)雜類型的數(shù)據(jù),比如對(duì)象類型的數(shù)組,二維數(shù)組,這些是無法判斷的.

          const?arr?=?['es6',?['es7',?'es8'],?'es9',{name:"jimmy"}]
          console.log(arr.includes(["es7",?"es8"]));?//?false
          console.log(arr.includes({name:"jimmy"}));?//?false
          復(fù)制代碼

          能識(shí)別NaN,indexOf是不能識(shí)別NaN的

          const?arr?=?['es6',?'es7',?NaN,?'es8']
          console.log(arr.includes(NaN))?//?true
          console.log(arr.indexOf(NaN))?//?-1
          復(fù)制代碼

          最后,如果只想知道某個(gè)值是否在數(shù)組中存在,而并不關(guān)心它的索引位置,建議使用includes(),如果想獲取一個(gè)值在數(shù)組中的位置,那么使用indexOf方法。

          冪運(yùn)算符 **

          比如我們想求2的10次方。

          自己寫函數(shù)實(shí)現(xiàn)

          function?pow(x,?y)?{
          ????let?result?=?1
          ????for?(let?i?=?0;?i?????????result?*=?x
          ????}
          ????return?result
          }
          console.log(pow(2,?10))?//?1024
          復(fù)制代碼

          Math.pow()

          console.log(Math.pow(2,?10));?//?1024
          復(fù)制代碼

          冪運(yùn)算符 **

          console.log(2?**?10);?//?1024
          復(fù)制代碼

          基本求冪

          2?**?3???//?8
          3?**?2???//?9
          3?**?2.5?//?15.588457268119896
          10?**?-1?//?0.1
          NaN?**?2?//?NaN
          復(fù)制代碼

          注意

          冪運(yùn)算符的兩個(gè)*號(hào)之間不能出現(xiàn)空格,否則語法會(huì)報(bào)錯(cuò)。

          ES2017(ES8)

          Object.values()

          Object.values 方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值。

          const?obj?=?{
          ??name:?"jimmy",
          ??age:?18,
          ??height:?188,
          };
          console.log(Object.values(obj));?//?[?'jimmy',?18,?188?]
          復(fù)制代碼

          Object.entries()

          Object.entries() 方法返回一個(gè)數(shù)組,成員是參數(shù)對(duì)象自身的(不含繼承的)所有可遍歷屬性的鍵值對(duì)數(shù)組。

          const?obj?=?{
          ??name:?"jimmy",
          ??age:?18,
          ??height:?188,
          };
          console.log(Object.entries(obj));?//?[?[?'name',?'jimmy'?],?[?'age',?18?],?[?'height',?188?]?]
          console.log(Object.entries([1,?2,?3]));?//?[?[?'0',?1?],?[?'1',?2?],?[?'2',?3?]?]
          復(fù)制代碼

          Object.getOwnPropertyDescriptors()

          Object.getOwnPropertyDescriptors() ?方法用來獲取一個(gè)對(duì)象的所有自身屬性的描述符。

          const?obj?=?{
          ??name:?"jimmy",
          ??age:?18,
          };
          const?desc?=?Object.getOwnPropertyDescriptors(obj);
          console.log(desc);??
          //?打印結(jié)果
          {
          ??name:?{
          ????value:?'jimmy',
          ????writable:?true,
          ????enumerable:?true,
          ????configurable:?true
          ??},
          ??age:?{?
          ???value:?18,?
          ???writable:?true,
          ???enumerable:?true,?
          ???configurable:?true?
          ??}
          }
          復(fù)制代碼

          上面打印結(jié)果中的

          • value表示當(dāng)前對(duì)象的默認(rèn)值
          • writable表示對(duì)象屬性是否可以修改
          • enumerable表示當(dāng)前這個(gè)屬性是否可以出現(xiàn)在對(duì)象的枚舉屬性中
          • configurable表示當(dāng)前對(duì)象的屬性能否用delete刪除

          那這些對(duì)象的屬性我們?cè)趺丛O(shè)置和修改他們呢,我們可以使用es5的 Object.defineProperty()

          const?obj?=?{};
          Object.defineProperty(obj,?"name",?{
          ??value:?"jimmy",
          ??writable:?true,
          ??configurable:?true,
          ??enumerable:?true,
          });
          Object.defineProperty(obj,?"age",?{
          ??value:?34,
          ??writable:?true,
          ??configurable:?true,
          ??enumerable:?true,
          });
          console.log(obj);?//?{?name:?'jimmy',?age:?34?}
          復(fù)制代碼

          接下來我們演示下,一些屬性設(shè)置為false的情況

          const?obj?=?{};
          Object.defineProperty(obj,?"name",?{
          ??value:?"jimmy",
          ??writable:?false,
          ??configurable:?false,
          ??enumerable:?true,
          });
          console.log(obj);?//?{?name:?'jimmy'?}
          obj.name?=?"chimmy";
          console.log(obj);?//?{?name:?'jimmy'?}
          delete?obj.name
          console.log(obj);?//?{?name:?'jimmy'?}
          復(fù)制代碼

          我們可以看到設(shè)置 writable: false和configurable: false,為false時(shí),對(duì)象的name對(duì)象的值不能改變和不能被刪除,打印出來還是原來的對(duì)象。

          設(shè)置enumerable為false時(shí)

          const?obj?=?{};
          Object.defineProperty(obj,?"name",?{
          ??value:?"jimmy",
          ??writable:?true,
          ??configurable:?true,
          ??enumerable:?false,
          });
          console.log(obj);?//?{?}
          for?(let?key?in?obj)?{
          ??console.log(key);?//?""
          }
          復(fù)制代碼

          當(dāng)設(shè)置enumerable: false時(shí),表示對(duì)象的屬性不可被枚舉,這時(shí)打印對(duì)象為空,遍歷對(duì)象的鍵也為空。

          String.prototype.padStart

          把指定字符串填充到字符串頭部,返回新字符串。

          語法

          str.padStart(targetLength [, padString])

          • targetLength

          當(dāng)前字符串需要填充到的目標(biāo)長(zhǎng)度。如果這個(gè)數(shù)值小于當(dāng)前字符串的長(zhǎng)度,則返回當(dāng)前字符串本身。

          • padString?可選

          填充字符串。如果字符串太長(zhǎng),使填充后的字符串長(zhǎng)度超過了目標(biāo)長(zhǎng)度,則只保留最左側(cè)的部分,其他部分會(huì)被截?cái)?。此參?shù)的默認(rèn)值為 " "

          示例

          'abc'.padStart(10);?????????//?"???????abc"
          'abc'.padStart(10,?"foo");??//?"foofoofabc"
          'abc'.padStart(6,"123465");?//?"123abc"
          'abc'.padStart(8,?"0");?????//?"00000abc"
          'abc'.padStart(1);??????????//?"abc"
          復(fù)制代碼

          應(yīng)用場(chǎng)景

          日期格式化:yyyy-mm-dd的格式:

          const?now?=?new?Date()
          const?year?=?now.getFullYear()
          //?月份和日期?如果是一位前面給它填充一個(gè)0
          const?month?=?(now.getMonth()?+?1).toString().padStart(2,?'0')
          const?day?=?(now.getDate()).toString().padStart(2,?'0')
          console.log(year,?month,?day)
          console.log(?`${year}-${month}-${day}`?)?//輸入今天的日期?2021-12-31
          復(fù)制代碼

          數(shù)字替換(手機(jī)號(hào),銀行卡號(hào)等)

          const?tel?=?'18781268679'
          const?newTel?=?tel.slice(-4).padStart(tel.length,?'*')
          console.log(newTel)?//?*******5678
          復(fù)制代碼

          String.prototype.padEnd

          把指定字符串填充到字符串尾部,返回新字符串。

          語法同上

          示例

          'abc'.padEnd(10);??????????//?"abc???????"
          'abc'.padEnd(10,?"foo");???//?"abcfoofoof"
          'abc'.padEnd(6,?"123456");?//?"abc123"
          'abc'.padEnd(1);???????????//?"abc"
          復(fù)制代碼

          應(yīng)用場(chǎng)景

          在JS前端我們處理時(shí)間戳的時(shí)候單位是ms毫秒,但是,后端同學(xué)返回的時(shí)間戳則不一樣是毫秒,可能只有10位,以s秒為單位。所以,我們?cè)谇岸颂幚磉@個(gè)時(shí)間戳的時(shí)候,保險(xiǎn)起見,要先做一個(gè)13位的補(bǔ)全,保證單位是毫秒。

          //?偽代碼
          console.log(new?Date().getTime())?//?時(shí)間戳?13位的
          timestamp?=?+String(timestamp).padEnd(13,?'0')
          復(fù)制代碼

          尾逗號(hào) Trailing commas

          ES8 允許函數(shù)的最后一個(gè)參數(shù)有尾逗號(hào)(Trailing comma)。此前,函數(shù)定義和調(diào)用時(shí),都不允許最后一個(gè)參數(shù)后面出現(xiàn)逗號(hào)。

          function?clownsEverywhere(
          ????param1,
          ????param2
          )?
          {
          ????/*?...?*/
          }

          clownsEverywhere(
          ????'foo',
          ????'bar'
          )
          復(fù)制代碼

          上面代碼中,如果在param2或bar后面加一個(gè)逗號(hào),就會(huì)報(bào)錯(cuò)。

          如果像上面這樣,將參數(shù)寫成多行(即每個(gè)參數(shù)占據(jù)一行),以后修改代碼的時(shí)候,想為函數(shù)clownsEverywhere添加第三個(gè)參數(shù),或者調(diào)整參數(shù)的次序,就勢(shì)必要在原來最后一個(gè)參數(shù)后面添加一個(gè)逗號(hào)。這對(duì)于版本管理系統(tǒng)來說,就會(huì)顯示添加逗號(hào)的那一行也發(fā)生了變動(dòng)。這看上去有點(diǎn)冗余,因此新的語法允許定義和調(diào)用時(shí),尾部直接可以加上一個(gè)逗號(hào)。

          function?clownsEverywhere(
          ????param1,
          ????param2,
          )?
          {
          ????/*?...?*/
          }

          clownsEverywhere(
          ????'foo',
          ????'bar',
          )
          復(fù)制代碼

          這樣的規(guī)定也使得,函數(shù)參數(shù)與數(shù)組和對(duì)象的尾逗號(hào)規(guī)則,保持一致了。

          async/await

          介紹

          我們都知道使用 Promise 能很好地解決回調(diào)地獄的問題,但如果處理流程比較復(fù)雜的話,那么整段代碼將充斥著 then,語義化不明顯,代碼不能很好地表示執(zhí)行流程,那有沒有比 Promise 更優(yōu)雅的異步方式呢?那就是async/await!我們一起來揭開它神秘的面撒吧!

          前面添加了async的函數(shù)在執(zhí)行后都會(huì)自動(dòng)返回一個(gè)Promise對(duì)象:

          function?foo()?{
          ????return?'jimmy'
          }
          console.log(foo())?//?'jimmy'
          復(fù)制代碼

          添加async后

          async?function?foo()?{
          ????return?'jimmy'?//?Promise.resolve('jimmy')
          }
          console.log(foo())?//?Promise
          foo()
          復(fù)制代碼

          async函數(shù)中使用await,那么await這里的代碼就會(huì)變成同步的了,意思就是說只有等await后面的Promise執(zhí)行完成得到結(jié)果才會(huì)繼續(xù)下去,await就是等待。請(qǐng)看下面的示例:

          function?timeout()?{
          ????return?new?Promise(resolve?=>?{
          ????????setTimeout(()?=>?{
          ????????????console.log(1)
          ????????????resolve()
          ????????},?1000)
          ????})
          }

          //?不加async和await是2、1???加了是1、2
          async?function?foo()?{
          ????await?timeout()?
          ????console.log(2)
          }
          foo()
          復(fù)制代碼

          使用場(chǎng)景

          假如有這樣一個(gè)使用場(chǎng)景:需要先請(qǐng)求 a 鏈接,等返回信息之后,再請(qǐng)求 b 鏈接的另外一個(gè)資源。下面代碼展示的是使用 fetch 來實(shí)現(xiàn)這樣的需求,fetch 被定義在 window 對(duì)象中,它返回的是一個(gè) Promise 對(duì)象。

          fetch('https://blog.csdn.net/')
          ??.then(response?=>?{
          ????console.log(response)
          ????return?fetch('https://juejin.im/')
          ??})
          ??.then(response?=>?{
          ????console.log(response)
          ??})
          ??.catch(error?=>?{
          ????console.log(error)
          ??})
          復(fù)制代碼

          雖然上述代碼可以實(shí)現(xiàn)這個(gè)需求,但語義化不明顯,代碼不能很好地表示執(zhí)行流程?;谶@個(gè)原因,ES8 引入了 async/await,這是 JavaScript 異步編程的一個(gè)重大改進(jìn),提供了在不阻塞主線程的情況下使用同步代碼實(shí)現(xiàn)異步訪問資源的能力,并且使得代碼邏輯更加清晰。

          async?function?foo?()?{
          ??try?{
          ????let?response1?=?await?fetch('https://blog.csdn.net/')
          ????console.log(response1)
          ????let?response2?=?await?fetch('https://juejin.im/')
          ????console.log(response2)
          ??}?catch?(err)?{
          ????console.error(err)
          ??}
          }
          foo()
          復(fù)制代碼

          通過上面代碼,你會(huì)發(fā)現(xiàn)整個(gè)異步處理的邏輯都是使用同步代碼的方式來實(shí)現(xiàn)的,而且還支持 try catch 來捕獲異常,這感覺就在寫同步代碼,所以是非常符合人的線性思維的。

          注意點(diǎn)

          • await 只能在 async 標(biāo)記的函數(shù)內(nèi)部使用,單獨(dú)使用會(huì)觸發(fā) Syntax error。

          • await后面需要跟異步操作,不然就沒有意義,而且await后面的Promise對(duì)象不必寫then,因?yàn)閍wait的作用之一就是獲取后面Promise對(duì)象成功狀態(tài)傳遞出來的參數(shù)。

          async/await的缺陷

          了解Async/await是非常有用的,但還有一些缺點(diǎn)需要考慮。

          Async/await?讓你的代碼看起來是同步的,在某種程度上,也使得它的行為更加地同步。?await?關(guān)鍵字會(huì)阻塞其后的代碼,直到promise完成,就像執(zhí)行同步操作一樣。它確實(shí)可以允許其他任務(wù)在此期間繼續(xù)運(yùn)行,但您自己的代碼被阻塞。

          這意味著您的代碼可能會(huì)因?yàn)榇罅?code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">await的promises相繼發(fā)生而變慢。每個(gè)await都會(huì)等待前一個(gè)完成,而你實(shí)際想要的是所有的這些promises同時(shí)開始處理(就像我們沒有使用async/await時(shí)那樣)。

          有一種模式可以緩解這個(gè)問題——通過將?Promise?對(duì)象存儲(chǔ)在變量中來同時(shí)開始它們,然后等待它們?nèi)繄?zhí)行完畢。如果想更加深入的了解,請(qǐng)參考 MDN[1]

          ES2018(ES9)

          Object Rest & Spread

          在 ES9 新增 Object 的 Rest & Spread 方法,直接看下示例:

          const?input?=?{
          ??a:?1,
          ??b:?2,
          ??c:?3,
          }

          const?output?=?{
          ??...input,
          ??c:?4
          }

          console.log(output)?//?{a:?1,?b:?2,?c:?4}
          復(fù)制代碼

          這塊代碼展示了 spread 語法,可以把 input 對(duì)象的數(shù)據(jù)都拓展到 output 對(duì)象,這個(gè)功能很實(shí)用。需要注意的是,如果存在相同的屬性名,只有最后一個(gè)會(huì)生效

          注意點(diǎn)

          const?obj?=?{?x:?{?y:?10?}?};
          const?copy1?=?{?...obj?};
          const?copy2?=?{?...obj?};
          obj.x.y?=?"jimmy";
          console.log(copy1,?copy2);?//?x:?{y:?"jimmy"}?x:?{y:?"jimmy"}
          console.log(copy1.x?===?copy2.x);?//?→?true
          復(fù)制代碼

          如果屬性的值是一個(gè)對(duì)象的話,該對(duì)象的引用會(huì)被拷貝,而不是生成一個(gè)新的對(duì)象。

          我們?cè)賮砜聪?Object rest 的示例:

          const?input?=?{
          ??a:?1,
          ??b:?2,
          ??c:?3
          }

          let?{?a,?...rest?}?=?input

          console.log(a,?rest)?//?1?{b:?2,?c:?3}
          復(fù)制代碼

          當(dāng)對(duì)象 key-value 不確定的時(shí)候,把必選的 key 賦值給變量,用一個(gè)變量收斂其他可選的 key 數(shù)據(jù),這在之前是做不到的。注意,rest 屬性必須始終出現(xiàn)在對(duì)象的末尾,否則將拋出錯(cuò)誤。

          for await of

          異步迭代器(for-await-of):循環(huán)等待每個(gè)Promise對(duì)象變?yōu)閞esolved狀態(tài)才進(jìn)入下一步。

          我們知道 for...of 是同步運(yùn)行的,看如下代碼

          function?TimeOut(time){
          ????return?new?Promise(function(resolve,?reject)?{
          ????????setTimeout(function()?{
          ????????????resolve(time)
          ????????},?time)
          ????})
          }

          async?function?test()?{
          ????let?arr?=?[TimeOut(2000),?TimeOut(1000),?TimeOut(3000)]
          ????for?(let?item?of?arr)?{??
          ?????console.log(Date.now(),item.then(console.log))
          ????}
          }

          test()
          復(fù)制代碼

          上面打印結(jié)果如下圖

          1640436987(1).png

          上述代碼證實(shí)了 for of 方法不能遍歷異步迭代器,得到的結(jié)果并不是我們所期待的,于是 for await of 就粉墨登場(chǎng)啦!

          ES9 中可以用 for...await...of 的語法來操作

          function?TimeOut(time)?{
          ????return?new?Promise(function(resolve,?reject)?{
          ????????setTimeout(function()?{
          ????????????resolve(time)
          ????????},?time)
          ????})
          }

          async?function?test()?{
          ????let?arr?=?[TimeOut(2000),?TimeOut(1000),?TimeOut(3000)]
          ????for?await?(let?item?of?arr)?{
          ????????console.log(Date.now(),?item)
          ????}
          }
          test()
          //?1560092345730?2000
          //?1560092345730?1000
          //?1560092346336?3000

          復(fù)制代碼

          for await of 環(huán)等待每個(gè)Promise對(duì)象變?yōu)閞esolved狀態(tài)才進(jìn)入下一步。所有打印的結(jié)果為 2000,1000,3000

          Promise.prototype.finally()

          Promise.prototype.finally() 方法返回一個(gè)Promise,在promise執(zhí)行結(jié)束時(shí),無論結(jié)果是fulfilled或者是rejected,在執(zhí)行then()和catch()后,都會(huì)執(zhí)行finally指定的回調(diào)函數(shù)。這為指定執(zhí)行完promise后,無論結(jié)果是fulfilled還是rejected都需要執(zhí)行的代碼提供了一種方式,避免同樣的語句需要在then()和catch()中各寫一次的情況。

          示例

          new?Promise((resolve,?reject)?=>?{
          ????setTimeout(()?=>?{
          ????????resolve('success')
          ????????//?reject('fail')
          ????},?1000)
          }).then(res?=>?{
          ????console.log(res)
          }).catch(err?=>?{
          ????console.log(err)
          }).finally(()?=>?{
          ????console.log('finally')
          })
          復(fù)制代碼

          使用場(chǎng)景

          loading關(guān)閉

          需要每次發(fā)送請(qǐng)求,都會(huì)有l(wèi)oading提示,請(qǐng)求發(fā)送完畢,就需要關(guān)閉loading提示框,不然界面就無法被點(diǎn)擊。不管請(qǐng)求成功或是失敗,這個(gè)loading都需要關(guān)閉掉,這時(shí)把關(guān)閉loading的代碼寫在finally里再合適不過了

          String 擴(kuò)展

          放松對(duì)標(biāo)簽?zāi)0謇镒址D(zhuǎn)義的限制, 遇到不合法的字符串轉(zhuǎn)義會(huì)返回undefined,并且從raw上可獲取原字符串。

          下面是一個(gè)es6 的標(biāo)簽?zāi)0?如果對(duì)這個(gè)語法感到陌生,請(qǐng)參考 標(biāo)簽?zāi)0?/span>[2]

          const?foo?=?(a,?b,?c)?=>?{
          ????console.log(a)
          ????console.log(b)
          ????console.log(c)
          }
          const?name?=?'jimmy'
          const?age?=?18
          foo?`這是${name},他的年齡是${age}歲`?


          復(fù)制代碼

          參數(shù)打印如下:

          ES9開始,模板字符串允許嵌套支持常見轉(zhuǎn)義序列,移除對(duì)ECMAScript在帶標(biāo)簽的模版字符串中轉(zhuǎn)義序列的語法限制。

          function?foo(a,?b,?c)?{
          ????console.log(a,?b,?c)
          }
          //?在標(biāo)簽函數(shù)中使用?
          //?unicode字符\u{61}?對(duì)應(yīng)的值為?a
          //?unicode字符\u{62}?對(duì)應(yīng)的值為?b
          //?\unicode?是一個(gè)無效的unicode字符
          foo?`\u{61}?and?\u{62}`?
          foo?`\u{61}?and?\unicode`??
          復(fù)制代碼
          1640441321(1).png

          注意點(diǎn)

          在模板字符串中,如果輸入無效的unicode字符,還是會(huì)報(bào)錯(cuò)。只有在便簽?zāi)0逯?從es9開始才不會(huì)報(bào)錯(cuò)。

          ?let?string?=?`\u{61}?and?\unicode`;
          ?console.log(string);?//?Uncaught?SyntaxError:?Invalid?Unicode?escape?sequence
          復(fù)制代碼

          ES2019(ES10)

          Object.fromEntries()

          方法 Object.fromEntries() 把鍵值對(duì)列表轉(zhuǎn)換為一個(gè)對(duì)象,這個(gè)方法是和 Object.entries() 相對(duì)的。

          Object.fromEntries([
          ????['foo',?1],
          ????['bar',?2]
          ])
          //?{foo:?1,?bar:?2}
          復(fù)制代碼

          案例1:Object 轉(zhuǎn)換操作

          const?obj?=?{
          ????name:?'jimmy',
          ????age:?18
          }
          const?entries?=?Object.entries(obj)
          console.log(entries)
          //?[Array(2),?Array(2)]

          //?ES10
          const?fromEntries?=?Object.fromEntries(entries)
          console.log(fromEntries)
          //?{name:?"jimmy",?age:?18}
          復(fù)制代碼

          案例2:Map 轉(zhuǎn) Object

          const?map?=?new?Map()
          map.set('name',?'jimmy')
          map.set('age',?18)
          console.log(map)?//?{'name'?=>?'jimmy',?'age'?=>?18}

          const?obj?=?Object.fromEntries(map)
          console.log(obj)
          //?{name:?"jimmy",?age:?18}
          復(fù)制代碼

          案例3:過濾

          course表示所有課程,想請(qǐng)求課程分?jǐn)?shù)大于80的課程組成的對(duì)象:

          const?course?=?{
          ????math:?80,
          ????english:?85,
          ????chinese:?90
          }
          const?res?=?Object.entries(course).filter(([key,?val])?=>?val?>?80)
          console.log(res)?//?[?[?'english',?85?],?[?'chinese',?90?]?]
          console.log(Object.fromEntries(res))?//?{?english:?85,?chinese:?90?}
          復(fù)制代碼

          案例4:url的search參數(shù)轉(zhuǎn)換

          //?let?url?=?"https://www.baidu.com?name=jimmy&age=18&height=1.88"
          //?queryString?為?window.location.search
          const?queryString?=?"?name=jimmy&age=18&height=1.88";
          const?queryParams?=?new?URLSearchParams(queryString);
          const?paramObj?=?Object.fromEntries(queryParams);
          console.log(paramObj);?//?{?name:?'jimmy',?age:?'18',?height:?'1.88'?}
          復(fù)制代碼

          Array.prototype.flat()

          語法

          let?newArray?=?arr.flat([depth])
          復(fù)制代碼
          • depth?可選

          指定要提取嵌套數(shù)組的結(jié)構(gòu)深度,默認(rèn)值為 1。

          示例

          flat() ?方法會(huì)按照一個(gè)可指定的深度遞歸遍歷數(shù)組,并將所有元素與遍歷到的子數(shù)組中的元素合并為一個(gè)新數(shù)組返回。

          const?arr1?=?[0,?1,?2,?[3,?4]];
          console.log(arr1.flat());??//??[0,?1,?2,?3,?4]
          const?arr2?=?[0,?1,?2,?[[[3,?4]]]];
          console.log(arr2.flat(2));??//??[0,?1,?2,?[3,?4]]

          //使用?Infinity,可展開任意深度的嵌套數(shù)組
          var?arr4?=?[1,?2,?[3,?4,?[5,?6,?[7,?8,?[9,?10]]]]];
          arr4.flat(Infinity);?//?[1,?2,?3,?4,?5,?6,?7,?8,?9,?10]

          //?`flat()`?方法會(huì)移除數(shù)組中的空項(xiàng):
          var?arr5?=?[1,?2,?,?4,?5];
          arr5.flat();?//?[1,?2,?4,?5]
          復(fù)制代碼

          Array.prototype.flatMap()

          flatMap() 方法首先使用映射函數(shù)映射每個(gè)元素,然后將結(jié)果壓縮成一個(gè)新數(shù)組。從方法的名字上也可以看出來它包含兩部分功能一個(gè)是 map,一個(gè)是 flat(深度為1)。

          語法

          var?new_array?=?arr.flatMap(function?callback(currentValue[,?index[,?array]])?{
          ????//?返回新數(shù)組的元素
          }[,?thisArg])
          復(fù)制代碼
          • callback

          可以生成一個(gè)新數(shù)組中的元素的函數(shù),可以傳入三個(gè)參數(shù):

          currentValue

          當(dāng)前正在數(shù)組中處理的元素

          index

          可選 數(shù)組中正在處理的當(dāng)前元素的索引。

          array

          可選 被調(diào)用的?map?數(shù)組

          • thisArg可選

          執(zhí)行?callback?函數(shù)時(shí)?使用的this?值。

          示例

          const?numbers?=?[1,?2,?3]
          numbers.map(x?=>?[x?*?2])?//?[[2],?[4],?[6]]
          numbers.flatMap(x?=>?[x?*?2])?//?[2,?4,?6]
          復(fù)制代碼

          這個(gè)示例可以簡(jiǎn)單對(duì)比下 map 和 flatMap 的區(qū)別。當(dāng)然還可以看下下面的示例:

          let?arr?=?['今天天氣不錯(cuò)',?'',?'早上好']
          arr.map(s?=>?s.split(''))
          //?[["今",?"天",?"天",?"氣",?"不",?"錯(cuò)"],[""],["早",?"上",?"好"]]
          arr.flatMap(s?=>?s.split(''))
          //?["今",?"天",?"天",?"氣",?"不",?"錯(cuò)",?"",?"早",?"上",?"好"]
          復(fù)制代碼

          flatMap?方法與?map?方法和深度depth為1的?flat?幾乎相同.

          String.prototype.trimStart()

          trimStart() 方法從字符串的開頭刪除空格,trimLeft()是此方法的別名。

          let?str?=?'???foo??'
          console.log(str.length)?//?8
          str?=?str.trimStart()?//?或str.trimLeft()
          console.log(str.length)?//?5
          復(fù)制代碼

          String.prototype.trimEnd()

          trimEnd() 方法從一個(gè)字符串的右端移除空白字符,trimRight 是 trimEnd 的別名。

          let?str?=?'???foo??'
          console.log(str.length)?//?8
          str?=?str.trimEnd()?//?或str.trimRight()
          console.log(str.length)?//?6
          復(fù)制代碼

          可選的Catch Binding

          在 ES10 之前我們都是這樣捕獲異常的:

          try?{
          ????//?tryCode
          }?catch?(err)?{
          ????//?catchCode
          }
          復(fù)制代碼

          在這里 err 是必須的參數(shù),在 ES10 可以省略這個(gè)參數(shù):

          try?{
          ????console.log('Foobar')
          }?catch?{
          ????console.error('Bar')
          }
          復(fù)制代碼

          應(yīng)用

          驗(yàn)證參數(shù)是否為json格式

          這個(gè)需求我們只需要返回true或false,并不關(guān)心catch的參數(shù)。

          const?validJSON?=?json?=>?{
          ????try?{
          ????????JSON.parse(json)
          ????????return?true
          ????}?catch?{
          ????????return?false
          ????}
          }
          復(fù)制代碼

          Symbol.prototype.description

          我們知道,Symbol 的描述只被存儲(chǔ)在內(nèi)部的?Description?,沒有直接對(duì)外暴露,我們只有調(diào)用 Symbol 的 toString() 時(shí)才可以讀取這個(gè)屬性:

          const?name?=?Symbol('es')
          console.log(name.toString())?//?Symbol(es)
          console.log(name)?//?Symbol(es)
          console.log(name?===?'Symbol(es)')?//?false
          console.log(name.toString()?===?'Symbol(es)')?//?true
          復(fù)制代碼

          現(xiàn)在可以通過 description 方法獲取 Symbol 的描述:

          const?name?=?Symbol('es')
          console.log(name.description)?//?es
          name.description?=?"es2"?//?只讀屬性?并不能修改描述符
          console.log(name.description?===?'es')?//?true
          //?如果沒有描述符?輸入undefined
          const?s2?=?Symbol()
          console.log(s2.description)?//?undefined

          復(fù)制代碼

          JSON.stringify() 增強(qiáng)能力

          JSON.stringify 在 ES10 修復(fù)了對(duì)于一些超出范圍的 Unicode 展示錯(cuò)誤的問題。因?yàn)?JSON 都是被編碼成 UTF-8,所以遇到 0xD800–0xDFFF 之內(nèi)的字符會(huì)因?yàn)闊o法編碼成 UTF-8 進(jìn)而導(dǎo)致顯示錯(cuò)誤。在 ES10 它會(huì)用轉(zhuǎn)義字符的方式來處理這部分字符而非編碼的方式,這樣就會(huì)正常顯示了。

          //?\uD83D\uDE0E??emoji?多字節(jié)的一個(gè)字符
          console.log(JSON.stringify('\uD83D\uDE0E'))?//?打印出笑臉

          //?如果我們只去其中的一部分??\uD83D?這其實(shí)是個(gè)無效的字符串
          //?之前的版本?,這些字符將替換為特殊字符,而現(xiàn)在將未配對(duì)的代理代碼點(diǎn)表示為JSON轉(zhuǎn)義序列
          console.log(JSON.stringify('\uD83D'))?//?"\ud83d"
          復(fù)制代碼

          修訂 Function.prototype.toString()

          以前函數(shù)的toString方法來自O(shè)bject.prototype.toString(),現(xiàn)在的 Function.prototype.toString() 方法返回一個(gè)表示當(dāng)前函數(shù)源代碼的字符串。以前只會(huì)返回這個(gè)函數(shù),不包含注釋、空格等。

          function?foo()?{
          ????//?es10新特性
          ????console.log('imooc')
          }
          console.log(foo.toString())?
          //?打印如下
          //?function?foo()?{
          //??//?es10新特性
          //??console.log("imooc");
          //?}
          復(fù)制代碼

          將返回注釋、空格和語法等詳細(xì)信息。

          ES2020(ES11)

          空值合并運(yùn)算符(Nullish coalescing Operator)

          空值合并操作符?? )是一個(gè)邏輯操作符,當(dāng)左側(cè)的操作數(shù)為?null或者undefined時(shí),返回其右側(cè)操作數(shù),否則返回左側(cè)操作數(shù)。

          const?foo?=?undefined????"foo"
          const?bar?=?null????"bar"
          console.log(foo)?//?foo
          console.log(bar)?//?bar
          復(fù)制代碼

          與邏輯或操作符(||)不同,邏輯或操作符會(huì)在左側(cè)操作數(shù)為假值時(shí)返回右側(cè)操作數(shù)。也就是說,如果使用?||?來為某些變量設(shè)置默認(rèn)值,可能會(huì)遇到意料之外的行為。比如為假值(例如'',0,NaN,false)時(shí)。見下面的例子。

          const?foo?=?""????'default?string';
          const?foo2?=?""?||?'default?string';
          console.log(foo);?//?""
          console.log(foo2);?//?"default?string"

          const?baz?=?0????42;
          const?baz2?=?0?||?42;
          console.log(baz);?//?0
          console.log(baz2);?//?42

          復(fù)制代碼

          注意點(diǎn)

          將????直接與?AND(&&)和 OR(||)操作符組合使用是不可取的。

          null?||?undefined????"foo";?//?拋出?SyntaxError
          true?||?undefined????"foo";?//?拋出?SyntaxError
          復(fù)制代碼

          可選鏈 Optional chaining

          介紹

          可選鏈操作符(??.?)允許讀取位于連接對(duì)象鏈深處的屬性的值,而不必明確驗(yàn)證鏈中的每個(gè)引用是否有效。?.?操作符的功能類似于?.?鏈?zhǔn)讲僮鞣?,不同之處在于,在引用?null?或者?undefined 的情況下不會(huì)引起錯(cuò)誤,該表達(dá)式短路返回值是?undefined。與函數(shù)調(diào)用一起使用時(shí),如果給定的函數(shù)不存在,則返回?undefined

          當(dāng)嘗試訪問可能不存在的對(duì)象屬性時(shí),可選鏈操作符將會(huì)使表達(dá)式更短、更簡(jiǎn)明。在探索一個(gè)對(duì)象的內(nèi)容時(shí),如果不能確定哪些屬性必定存在,可選鏈操作符也是很有幫助的。

          const?user?=?{
          ????address:?{
          ????????street:?'xx街道',
          ????????getNum()?{
          ????????????return?'80號(hào)'
          ????????}
          ????}
          }

          復(fù)制代碼

          在之前的語法中,想獲取到深層屬性或方法,不得不做前置校驗(yàn),否則很容易命中?Uncaught TypeError: Cannot read property...?這種錯(cuò)誤,這極有可能讓你整個(gè)應(yīng)用掛掉。

          const?street?=?user?&&?user.address?&&?user.address.street
          const?num?=?user?&&?user.address?&&?user.address.getNum?&&?user.address.getNum()
          console.log(street,?num)
          復(fù)制代碼

          用了 Optional Chaining ,上面代碼會(huì)變成

          const?street2?=?user?.address?.street
          const?num2?=?user?.address?.getNum?.()
          console.log(street2,?num2)
          復(fù)制代碼

          可選鏈中的 ? 表示如果問號(hào)左邊表達(dá)式有值, 就會(huì)繼續(xù)查詢問號(hào)后面的字段。根據(jù)上面可以看出,用可選鏈可以大量簡(jiǎn)化類似繁瑣的前置校驗(yàn)操作,而且更安全。

          常見用法

          ??//?對(duì)象中使用
          ??let?obj?=?{
          ????name:?"jimmy",
          ????age:?"18",
          ??};
          ??let?property?=?"age";
          ??let?name?=?obj?.name;
          ??let?age?=?obj?.age;
          ??let?ages?=?obj?.[property];
          ??let?sex?=?obj?.sex;
          ??console.log(name);?//?jimmy
          ??console.log(age);?//?18
          ??console.log(ages);?//?18
          ??console.log(sex);?//?undefined
          ??
          ??//?數(shù)組中使用
          ??let?arr?=?[1,2,2];
          ??let?arrayItem?=?arr?.[42];?//?undefined
          ??
          ??//?函數(shù)中使用
          ??let?obj?=?{
          ???func:?function?()?{
          ?????console.log("I?am?func");
          ???},
          ??};
          ??obj?.func();?//?I?am?func
          復(fù)制代碼

          與空值合并操作符一起使用

          let?customer?=?{
          ??name:?"jimmy",
          ??details:?{?age:?18?}
          };
          let?customerCity?=?customer?.city????"成都";
          console.log(customerCity);?//?"成都"
          復(fù)制代碼

          注意點(diǎn)

          可選鏈不能用于賦值

          let?object?=?{};
          object?.property?=?1;?//?Uncaught?SyntaxError:?Invalid?left-hand?side?in?assignment
          復(fù)制代碼

          globalThis

          在以前,從不同的 JavaScript 環(huán)境中獲取全局對(duì)象需要不同的語句。在 Web 中,可以通過?window、self?取到全局對(duì)象,在 Node.js 中,它們都無法獲取,必須使用?global

          在松散模式下,可以在函數(shù)中返回?this?來獲取全局對(duì)象,但是在嚴(yán)格模式和模塊環(huán)境下,this?會(huì)返回?undefined。

          以前想要獲取全局對(duì)象,可通過一個(gè)全局函數(shù)

          const?getGlobal?=?()?=>?{
          ????if?(typeof?self?!==?'undefined')?{
          ????????return?self
          ????}
          ????if?(typeof?window?!==?'undefined')?{
          ????????return?window
          ????}
          ????if?(typeof?global?!==?'undefined')?{
          ????????return?global
          ????}
          ????throw?new?Error('無法找到全局對(duì)象')
          }

          const?globals?=?getGlobal()
          console.log(globals)
          復(fù)制代碼

          現(xiàn)在globalThis?提供了一個(gè)標(biāo)準(zhǔn)的方式來獲取不同環(huán)境下的全局?this? 對(duì)象(也就是全局對(duì)象自身)。不像?window?或者?self?這些屬性,它確??梢栽谟袩o窗口的各種環(huán)境下正常工作。所以,你可以安心的使用?globalThis,不必?fù)?dān)心它的運(yùn)行環(huán)境。

          為便于記憶,你只需要記住,全局作用域中的?this?就是globalThis。以后就用globalThis就行了。

          BigInt

          BigInt?是一種內(nèi)置對(duì)象,它提供了一種方法來表示大于?2的53次方 \- 1?的整數(shù)。這原本是 Javascript中可以用?Number?表示的最大數(shù)字。BigInt?可以表示任意大的整數(shù)。

          使用 BigInt 有兩種方式:

          方式一:數(shù)字后面增加n

          const?bigInt?=?9007199254740993n
          console.log(bigInt)
          console.log(typeof?bigInt)?//?bigint

          //?`BigInt`?和?[`Number`]不是嚴(yán)格相等的,但是寬松相等的。
          console.log(1n?==?1)?//?true
          console.log(1n?===?1)?//?false

          //?`Number`?和?`BigInt`?可以進(jìn)行比較。
          1n?2?//???true
          2n?>?1?//???true

          復(fù)制代碼

          方式二:使用 BigInt 函數(shù)

          const?bigIntNum?=?BigInt(9007199254740993n)
          console.log(bigIntNum)
          復(fù)制代碼

          運(yùn)算

          let?number?=?BigInt(2);
          let?a?=?number?+?2n;?//?4n
          let?b?=?number?*?10n;?//?20n
          let?c?=?number?-?10n;?//?-8n
          console.log(a);
          console.log(b);
          console.log(c);
          復(fù)制代碼

          注意點(diǎn)

          BigInt不能用于?[Math]?對(duì)象中的方法;不能和任何?[Number]?實(shí)例混合運(yùn)算,兩者必須轉(zhuǎn)換成同一種類型。在兩種類型來回轉(zhuǎn)換時(shí)要小心,因?yàn)?BigInt?變量在轉(zhuǎn)換成?[Number]?變量時(shí)可能會(huì)丟失精度。

          String.prototype.matchAll()

          matchAll() ?方法返回一個(gè)包含所有匹配正則表達(dá)式的結(jié)果及分組捕獲組的迭代器。

          const?regexp?=?/t(e)(st(\d?))/g;
          const?str?=?'test1test2';

          const?array?=?[...str.matchAll(regexp)];
          console.log(array[0]);??//?["test1",?"e",?"st1",?"1"]
          console.log(array[1]);?//?["test2",?"e",?"st2",?"2"]
          復(fù)制代碼

          Promise.allSettled()

          我們都知道 Promise.all() 具有并發(fā)執(zhí)行異步任務(wù)的能力。但它的最大問題就是如果其中某個(gè)任務(wù)出現(xiàn)異常(reject),所有任務(wù)都會(huì)掛掉,Promise直接進(jìn)入reject 狀態(tài)。

          場(chǎng)景:現(xiàn)在頁面上有三個(gè)請(qǐng)求,分別請(qǐng)求不同的數(shù)據(jù),如果一個(gè)接口服務(wù)異常,整個(gè)都是失敗的,都無法渲染出數(shù)據(jù)

          我們需要一種機(jī)制,如果并發(fā)任務(wù)中,無論一個(gè)任務(wù)正?;蛘弋惓?,都會(huì)返回對(duì)應(yīng)的的狀態(tài),這就是Promise.allSettled的作用

          const?promise1?=?()?=>?{
          ??return?new?Promise((resolve,?reject)?=>?{
          ????setTimeout(()?=>?{
          ??????resolve("promise1");
          ??????//???reject("error?promise1?");
          ????},?3000);
          ??});
          };
          const?promise2?=?()?=>?{
          ??return?new?Promise((resolve,?reject)?=>?{
          ????setTimeout(()?=>?{
          ??????resolve("promise2");
          ??????//???reject("error?promise2?");
          ????},?1000);
          ??});
          };
          const?promise3?=?()?=>?{
          ??return?new?Promise((resolve,?reject)?=>?{
          ????setTimeout(()?=>?{
          ??????//???resolve("promise3");
          ??????reject("error?promise3?");
          ????},?2000);
          ??});
          };

          //??Promise.all?會(huì)走到catch里面
          Promise.all([promise1(),?promise2(),?promise3()])
          ??.then((res)?=>?{
          ????console.log(res);?
          ??})
          ??.catch((error)?=>?{
          ????console.log("error",?error);?//?error?promise3?
          ??});
          ??
          //?Promise.allSettled?不管有沒有錯(cuò)誤,三個(gè)的狀態(tài)都會(huì)返回
          Promise.allSettled([promise1(),?promise2(),?promise3()])
          ??.then((res)?=>?{
          ????console.log(res);??
          ????//?打印結(jié)果?
          ????//?[
          ????//????{status:?'fulfilled',?value:?'promise1'},?
          ????//????{status:?'fulfilled',value:?'promise2'},
          ????//????{status:?'rejected',?reason:?'error?promise3?'}
          ????//?]
          ??})
          ??.catch((error)?=>?{
          ????console.log("error",?error);?
          ??});
          復(fù)制代碼

          Dynamic Import(按需 import)

          import()可以在需要的時(shí)候,再加載某個(gè)模塊。

          button.addEventListener('click',?event?=>?{
          ??import('./dialogBox.js')
          ??.then(dialogBox?=>?{
          ????dialogBox.open();
          ??})
          ??.catch(error?=>?{
          ????/*?Error?handling?*/
          ??})
          });
          復(fù)制代碼

          上面代碼中,import()方法放在click事件的監(jiān)聽函數(shù)之中,只有用戶點(diǎn)擊了按鈕,才會(huì)加載這個(gè)模塊。

          ES2021(ES12)

          邏輯運(yùn)算符和賦值表達(dá)式(&&=,||=,??=)

          &&=

          邏輯與賦值 x &&= y等效于:

          x?&&?(x?=?y);
          復(fù)制代碼

          上面的意思是,當(dāng)x為真時(shí),x=y。具體請(qǐng)看下面的示例:

          let?a?=?1;
          let?b?=?0;

          a?&&=?2;
          console.log(a);?//?2

          b?&&=?2;
          console.log(b);??//?0
          復(fù)制代碼

          ||=

          邏輯或賦值(x ||= y)運(yùn)算僅在?x?為false時(shí)賦值。

          x ||= y?等同于:x || (x = y);

          const?a?=?{?duration:?50,?title:?''?};

          a.duration?||=?10;
          console.log(a.duration);?//?50

          a.title?||=?'title?is?empty.';
          console.log(a.title);?//?"title?is?empty"

          復(fù)制代碼

          ??=

          邏輯空賦值運(yùn)算符?(x ??= y) 僅在?x?是?nullish[3]?(null?或?undefined) 時(shí)對(duì)其賦值。

          x ??= y?等價(jià)于:x ?? (x = y);

          示例一

          const?a?=?{?duration:?50?};

          a.duration???=?10;
          console.log(a.duration);?//?50

          a.speed???=?25;
          console.log(a.speed);?//?25
          復(fù)制代碼

          示例二

          function?config(options)?{
          ??options.duration???=?100;
          ??options.speed???=?25;
          ??return?options;
          }

          config({?duration:?125?});?//?{?duration:?125,?speed:?25?}
          config({});?//?{?duration:?100,?speed:?25?}
          復(fù)制代碼

          String.prototype.replaceAll()

          介紹

          replaceAll() ?方法返回一個(gè)新字符串,新字符串中所有滿足?pattern?的部分都會(huì)被replacement?替換。pattern可以是一個(gè)字符串或一個(gè)RegExpreplacement可以是一個(gè)字符串或一個(gè)在每次匹配被調(diào)用的函數(shù)。

          原始字符串保持不變。

          示例

          'aabbcc'.replaceAll('b',?'.');?//?'aa..cc'
          復(fù)制代碼

          使用正則表達(dá)式搜索值時(shí),它必須是全局的。

          'aabbcc'.replaceAll(/b/,?'.');
          TypeError:?replaceAll?must?be?called?with?a?global?RegExp
          復(fù)制代碼

          這將可以正常運(yùn)行:

          'aabbcc'.replaceAll(/b/g,?'.');
          "aa..cc"
          復(fù)制代碼

          數(shù)字分隔符

          歐美語言中,較長(zhǎng)的數(shù)值允許每三位添加一個(gè)分隔符(通常是一個(gè)逗號(hào)),增加數(shù)值的可讀性。比如,1000可以寫作1,000。

          ES2021中允許 JavaScript 的數(shù)值使用下劃線(_)作為分隔符。

          let?budget?=?1_000_000_000_000;
          budget?===?10?**?12?//?true
          復(fù)制代碼

          這個(gè)數(shù)值分隔符沒有指定間隔的位數(shù),也就是說,可以每三位添加一個(gè)分隔符,也可以每一位、每?jī)晌弧⒚克奈惶砑右粋€(gè)。

          123_00?===?12_300?//?true

          12345_00?===?123_4500?//?true
          12345_00?===?1_234_500?//?true
          復(fù)制代碼

          小數(shù)和科學(xué)計(jì)數(shù)法也可以使用數(shù)值分隔符。

          //?小數(shù)
          0.000_001

          //?科學(xué)計(jì)數(shù)法
          1e10_000
          復(fù)制代碼

          數(shù)值分隔符有幾個(gè)使用注意點(diǎn)。

          • 不能放在數(shù)值的最前面(leading)或最后面(trailing)。
          • 不能兩個(gè)或兩個(gè)以上的分隔符連在一起。
          • 小數(shù)點(diǎn)的前后不能有分隔符。
          • 科學(xué)計(jì)數(shù)法里面,表示指數(shù)的eE前后不能有分隔符。

          下面的寫法都會(huì)報(bào)錯(cuò)。

          //?全部報(bào)錯(cuò)
          3_.141
          3._141
          1_e12
          1e_12
          123__456
          _1464301
          1464301_
          復(fù)制代碼

          Promise.any

          方法接受一組 Promise 實(shí)例作為參數(shù),包裝成一個(gè)新的 Promise 實(shí)例返回。

          const?promise1?=?()?=>?{
          ??return?new?Promise((resolve,?reject)?=>?{
          ????setTimeout(()?=>?{
          ??????resolve("promise1");
          ??????//??reject("error?promise1?");
          ????},?3000);
          ??});
          };
          const?promise2?=?()?=>?{
          ??return?new?Promise((resolve,?reject)?=>?{
          ????setTimeout(()?=>?{
          ??????resolve("promise2");
          ??????//?reject("error?promise2?");
          ????},?1000);
          ??});
          };
          const?promise3?=?()?=>?{
          ??return?new?Promise((resolve,?reject)?=>?{
          ????setTimeout(()?=>?{
          ??????resolve("promise3");
          ??????//?reject("error?promise3?");
          ????},?2000);
          ??});
          };
          Promise.any([promise1(),?promise2(),?promise3()])
          ??.then((first)?=>?{
          ????//?只要有一個(gè)請(qǐng)求成功?就會(huì)返回第一個(gè)請(qǐng)求成功的
          ????console.log(first);?//?會(huì)返回promise2
          ??})
          ??.catch((error)?=>?{
          ????//?所有三個(gè)全部請(qǐng)求失敗?才會(huì)來到這里
          ????console.log("error",?error);
          ??});
          復(fù)制代碼

          只要參數(shù)實(shí)例有一個(gè)變成fulfilled狀態(tài),包裝實(shí)例就會(huì)變成fulfilled狀態(tài);如果所有參數(shù)實(shí)例都變成rejected狀態(tài),包裝實(shí)例就會(huì)變成rejected狀態(tài)。

          Promise.any()Promise.race()方法很像,只有一點(diǎn)不同,就是Promise.any()不會(huì)因?yàn)槟硞€(gè) Promise 變成rejected狀態(tài)而結(jié)束,必須等到所有參數(shù) Promise 變成rejected狀態(tài)才會(huì)結(jié)束。

          WeakRef and Finalizers

          這兩個(gè)新特性,都應(yīng)該盡量避免使用,所以這里不做過多的講解。如感興趣,請(qǐng)參考

          WeakRef[4]

          Finalizers[5]


          關(guān)于本文

          作者:Jimmy_fx

          https://juejin.cn/post/7046217976176967711

          最后

          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
          回復(fù)「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會(huì)很認(rèn)真的解答喲!
          回復(fù)「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
          回復(fù)「閱讀」,每日刷刷高質(zhì)量好文!
          如果這篇文章對(duì)你有幫助,在看」是最大的支持
          ?》》面試官也在看的算法資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持
          瀏覽 38
          點(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>
                  先锋影音男人在线资源站 | 靠逼视频网站 | 日韩一级无码免费视频 | 国产精品久久久久久9999 | 日韩AVAV|