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

          面試刨根問到底:[...undefined] 執(zhí)行結(jié)果是什么

          共 3032字,需瀏覽 7分鐘

           ·

          2021-12-11 16:14

          據(jù)說面試中只有 5% 的人能講透徹,你會(huì)是其中之一嗎?

          [...undefined] 輸出什么?

          ... 可以稱之為 展開語法(Spread syntax),又可以叫 擴(kuò)展運(yùn)算符。可以在函數(shù)調(diào)用/數(shù)組構(gòu)造時(shí), 將數(shù)組表達(dá)式或者 string 在語法層面展開;還可以在構(gòu)造字面量對(duì)象時(shí), 將對(duì)象表達(dá)式按 key-value 的方式展開。

          首先我們來看數(shù)組中常見的用法:

          const foo = [1, 2, 3];
          const bar = [0, ...foo];

          console.log(bar);
          // [0, 1, 2, 3]

          這種方式類似數(shù)組中的 slice() ,將 foo 淺拷貝到 bar 數(shù)組里。

          我們?cè)跒g覽器上輸出結(jié)果:

          [...undefined]

          // Uncaught TypeError: undefined is not iterable

          看到代碼報(bào)錯(cuò) Uncaught TypeError,因?yàn)?undefined 是不可迭代的。那什么可迭代呢,試試普通對(duì)象:

          [...{}]

          // Uncaught TypeError: {} is not iterable

          從這里可以看出普通對(duì)象也不行。在數(shù)組或函數(shù)參數(shù)中使用展開語法時(shí), 該語法只能用于 可迭代對(duì)象

          什么是 可迭代對(duì)象

          要成為可迭代對(duì)象, 一個(gè)對(duì)象必須實(shí)現(xiàn) @@iterator 方法。這意味著對(duì)象(或者它原型鏈上的某個(gè)對(duì)象)必須有一個(gè)鍵為 @@iterator 的屬性,可通過常量 Symbol.iterator 訪問該屬性

          什么意思呢,看一個(gè)簡(jiǎn)單的例子最直接:

          const counter = {
          *[Symbol.iterator]() {
          yield 1;
          },
          };

          [...counter];
          // 正常執(zhí)行,結(jié)果:
          // [1]

          一個(gè)普通對(duì)象中,必須包含一個(gè) Symbol.iterator 屬性,并規(guī)定是一個(gè)無參數(shù)的函數(shù),其返回值為一個(gè)符合 迭代器協(xié)議 的對(duì)象。迭代器協(xié)議 屬于 迭代協(xié)議迭代協(xié)議 并不是新的內(nèi)置實(shí)現(xiàn)或語法,而是協(xié)議。這些協(xié)議可以被任何遵循某些約定的對(duì)象來實(shí)現(xiàn)。

          什么是迭代器?

          只有實(shí)現(xiàn)了 迭代器協(xié)議 的一個(gè)對(duì)象才能成為迭代器。例如:

          const counter = {
          next() {
          return { value: undefined, done: true };
          },
          };

          迭代器是通過使用 next() 方法實(shí)現(xiàn) 迭代器協(xié)議 的任何一個(gè)對(duì)象,該方法返回具有兩個(gè)屬性的對(duì)象:value,這是序列中的 next 值;和 done ,如果已經(jīng)迭代到序列中的最后一個(gè)值,則它為 true 。如果 valuedone 一起存在,則它是迭代器的返回值。

          可迭代對(duì)象迭代器 有什么區(qū)別呢?

          如果實(shí)現(xiàn)了 迭代器協(xié)議可迭代協(xié)議,那么它就是一個(gè) 可迭代對(duì)象

          const counter = {
          next() {
          return { value: undefined, done: true };
          },
          [Symbol.iterator]() {
          return this;
          },
          };

          [Symbol.iterator]() 通過返回 this 以便調(diào)用該方法后獲得一個(gè)迭代器,以下方式也許會(huì)更好理解:

          const counter = {
          [Symbol.iterator]() {
          // 返回一個(gè)迭代器
          return {
          next() {
          return { value: undefined, done: true };
          },
          };
          },
          };

          當(dāng)一個(gè)對(duì)象需要被迭代的時(shí)候,首先,會(huì)不帶參數(shù)調(diào)用它的 @@iterator 方法,然后使用此方法返回的迭代器獲得要迭代的值。此函數(shù)可以是普通函數(shù),也可以是生成器函數(shù),以便在調(diào)用時(shí)返回迭代器對(duì)象。在此生成器函數(shù)的內(nèi)部,可以使用 yield 提供每個(gè)條目。

          如果 @@iterator 方法不返回迭代器呢?

          const counter = {
          [Symbol.iterator]() {
          return 1;
          },
          };

          [...counter];
          // Uncaught TypeError: Result of the Symbol.iterator method is not an object

          如果一個(gè)可迭代對(duì)象的 @@iterator 方法不能返回迭代器對(duì)象,那么可以認(rèn)為它是一個(gè)不符合標(biāo)準(zhǔn)的可迭代對(duì)象。

          生成器(Generator)對(duì)象到底是一個(gè)迭代器,還是一個(gè)可迭代對(duì)象?

          生成器對(duì)象既是迭代器,也是可迭代對(duì)象,因?yàn)樗?可迭代協(xié)議迭代器協(xié)議

          function* gen() {
          yield 1;
          yield 2;
          yield 3;
          }

          [...gen()];
          // [1, 2, 3]

          那內(nèi)置可迭代對(duì)象有哪些呢?

          目前所有的內(nèi)置可迭代對(duì)象有:

          • String
          • Array
          • TypedArray
          • Map
          • Set
          • arguments
          • NodeList

          它們的原型對(duì)象都實(shí)現(xiàn)了 @@iterator 方法。

          那想實(shí)現(xiàn) [...obj] 展開一個(gè)普通對(duì)象,有辦法嗎?

          顧名思義,那就是要將普通對(duì)象轉(zhuǎn)換為 可迭代對(duì)象

          • 展開對(duì)象的 key[...Object.keys(obj)]
          • 展開對(duì)象的 value[...Object.values(obj)]
          • 展開整個(gè)對(duì)象:[...Object.entries(obj)]

          {...undefined} 執(zhí)行結(jié)果是什么?

          展開語法在字面量對(duì)象的行為細(xì)節(jié)與數(shù)組中有很大差別,可以看作是 Object.assign({}, undefined),主要區(qū)別是 Object.assign() 函數(shù)會(huì)觸發(fā) setters,而展開語法則不會(huì)

          執(zhí)行結(jié)果則是返回一個(gè) {} 空對(duì)象,{...true}{...1}{...null} 亦是如此。

          { ...[1, 2, 3] } 執(zhí)行結(jié)果呢?

          首先在對(duì)象中不能將 ... 后面當(dāng)作 可迭代對(duì)象 看待,應(yīng)該看作是一個(gè)普通對(duì)象,即包含 key

          { ...[1, 2, 3] }
          // {0: 1, 1: 2, 2: 3}

          那請(qǐng)說 ... 語法作為剩余參數(shù)的特性

          展開語法可以用于函數(shù)的最后一個(gè)命名參數(shù),它由剩余參數(shù)組成的真數(shù)組。它與 arguments 對(duì)象的區(qū)別主要有三個(gè):

          1. 剩余參數(shù)只包含那些沒有對(duì)應(yīng)形參的實(shí)參,而 arguments 對(duì)象包含了傳給函數(shù)的所有實(shí)參
          2. arguments 對(duì)象不是一個(gè)真正的數(shù)組,而剩余參數(shù)是真正的 Array 實(shí)例
          3. arguments 對(duì)象還有一些附加的屬性(如 callee 屬性)

          展開語法還可以用于數(shù)組/對(duì)象解構(gòu),剩余元素必須是數(shù)組/對(duì)象的最后一個(gè)元素。

          參考資料

          https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols



          一起變強(qiáng)!一起面向快樂編程!???

          長按/掃描添加我!

          回復(fù)?[加群],進(jìn)群與大佬們一起共同進(jìn)步!
          ?? ?


          點(diǎn)點(diǎn)贊

          點(diǎn)在看

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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91狠狠干| 九九九九精品在线 | 国产三级片电影成人久久久 | 东京热三级片 | 五月天开心色情网 |