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

          【JS】830- 為什么不推薦用for...in遍歷數(shù)組

          共 2026字,需瀏覽 5分鐘

           ·

          2021-01-11 11:25

          轉(zhuǎn)載自:沐碼小站

          https://wintc.top/article/49

          一、for...in引發(fā)的一個(gè)報(bào)錯(cuò)

          兩年前寫的一個(gè)文章目錄生成插件vue-outline,一直用著沒出啥問題(本站的文章目錄也是用該插件生成的)。但是最近一個(gè)網(wǎng)友在使用的時(shí)候卻出現(xiàn)了異常報(bào)錯(cuò),異常代碼使用了一個(gè)for...in遍歷數(shù)組:

          ??for?(let?idx?in?selectors)?{
          ????let?elementList?=?dom.querySelectorAll(selectors[idx])
          ????elementList.forEach(element?=>?{
          ??????if?(element.__nav_except?||?element.offsetParent?===?null)?return
          ??????element.__nav_level?=?idx
          ????})
          ??}

          代碼本意是,通過用戶給定的選擇器列表selectors確定哪些元素可以提取出來(lái)作為標(biāo)題,比如傳一個(gè)['h1', 'h3', 'div.title']。網(wǎng)友的使用方法完全正確,selectors傳遞的都是合法的選擇器,但是會(huì)出現(xiàn)以下報(bào)錯(cuò):

          img

          一個(gè)函數(shù)不是一個(gè)合法的選擇器?selectors里傳遞的都是選擇器。最后這位網(wǎng)友找到了原因,可能和for...in有關(guān)系,因?yàn)樗跀?shù)組的原型上添加了一些便捷的方法:

          img

          而for...in會(huì)遍歷出原型上的這些方法,這就導(dǎo)致在執(zhí)行前面的代碼時(shí),把一個(gè)函數(shù)作為參數(shù)傳遞給了querySelectorAll,導(dǎo)致報(bào)錯(cuò)!

          二、for...in細(xì)節(jié)

          for...in本身是Object的遍歷方法,JS中的數(shù)組也繼承自O(shè)bject,所以自然而然也能使用for...in遍歷出屬性。然而for...in有一些難以注意到的細(xì)節(jié),稍不注意就可能被坑。

          1. 細(xì)節(jié)一:遍歷的屬性值是字符串,而不是數(shù)字!(相信初接觸JS的人都要被坑一次吧)

          const?list?=?[1,?2,?3]
          for?(let?i?in?list)?{
          ????console.log(i,?i?+?1,?typeof?i)
          }

          打印:

          0?01?string
          1?11?string
          2?21?string

          可以看到typeof i的返回值是“string”,這個(gè)最坑的地方在于我們通過下標(biāo)加減想取別的元素時(shí),就會(huì)出現(xiàn)異常,像上述輸出的i + 1一樣,并不是數(shù)字相加,而是字符串拼接!

          2. 細(xì)節(jié)二:遍歷的是對(duì)象的枚舉屬性,包括自身屬性以及原型鏈上的屬性

          const?obj?=?{
          ??a:?'value_a',
          ??b:?'value_b'
          }

          Object.prototype.c?=?'proto_value_c'

          Object.defineProperty(obj,?'d',?{
          ??get?()?{?return?'value_d'?},
          ??enumerable:?false,
          })

          for?(let?key?in?obj)?{
          ??console.log(key,?obj[key])
          }

          輸出:

          a?value_a
          b?value_b
          c?proto_value_c

          可以看到,原型上的屬性c也打印出來(lái)了,但是通過Object.defineProperty定義的不可枚舉屬性d(enumerable: false)沒有被遍歷到。

          3. 細(xì)節(jié)三:遍歷順序是對(duì)象屬性的枚舉順序,并不一定按數(shù)組的下標(biāo)順序遍歷

          for...in的遍歷順序是枚舉順序,對(duì)于數(shù)組而言,規(guī)范并沒有約束各瀏覽器的實(shí)現(xiàn)。因此即便在一定范圍內(nèi)是按順序遍歷的,也應(yīng)該盡量不依賴for...in遍歷的順序。MDN文檔也明確指出,不建議使用for...in遍歷數(shù)組,特別是想按照索引順序遍歷的時(shí)候:


          此外,因?yàn)橛邢∈钄?shù)組的存在,其實(shí)JS里的數(shù)組不一定是順序結(jié)構(gòu)存儲(chǔ)的。當(dāng)數(shù)組的鍵分布較為稀疏,為了充分節(jié)約空間,數(shù)組可能會(huì)退化為像對(duì)象一樣的哈希表存儲(chǔ)結(jié)構(gòu)。

          因?yàn)閒or...in本身是對(duì)象的遍歷方法,并不適用于數(shù)組,對(duì)于數(shù)組,還是for...of、for循環(huán)、forEach等遍歷比較好。

          1. JavaScript 重溫系列(22篇全)
          2. ECMAScript 重溫系列(10篇全)
          3. JavaScript設(shè)計(jì)模式 重溫系列(9篇全)
          4.?正則 / 框架 / 算法等 重溫系列(16篇全)
          5.?Webpack4 入門(上)||?Webpack4 入門(下)
          6.?MobX 入門(上)?||??MobX 入門(下)
          7. 80+篇原創(chuàng)系列匯總

          回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~

          點(diǎn)擊“閱讀原文”查看 100+ 篇原創(chuàng)文章

          瀏覽 44
          點(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>
                  japαnese老熟女老熟妇 | 大香蕉欧美在线 | 91无码人妻 传媒tv | 伊人网站在线免费观看 | 天堂网黄|