搜尋
首頁web前端前端問答es6的for of可以遍歷對象嗎

es6的「for of」不能遍歷物件。原因:ES6中引入了Iterator接口,只有提供了Iterator接口的資料類型才可以使用“for-of”來循環遍歷;而普通對象默認沒有提供Iterator接口,因此無法用“for-of”來進行遍歷。

es6的for of可以遍歷對象嗎

本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

隨著前端的不斷發展,光循環就出現了好多種方法,for、forEach、do..while、for...in等等,不過這些循環也都各有各的應用場景和優缺點。

ES6又為我們提供了新的循環方法for...of,它可以循環字串、數組及其他類數組對象,那作為最普遍存在的Object對象,按理,可以循環?

我們來看看下方的程式碼範例:

{
    // 迭代数组
  const iterable = ['a', 'b'];
  for (const value of iterable) {
    console.log(value);
  }
  // output: a b
}
{
    // 普通对象
    const obj = {
      a: 'A',
      b: 'B'
    }
    for(const item of obj){
      console.log(item)
    }
    // Uncaught TypeError: obj is not iterable
}

oh no,報錯了:Uncaught TypeError: obj is not iterable。提示obj是不可迭代的,顯然直接用for...of去遍歷Object物件是不行的。

那麼可以遍歷大部分資料結構的for...of為何不能遍歷Object物件?

原因:

ES6 中引入了Iterator,只有提供了Iterator 介面的資料類型才可以使用for-of 來循環遍歷,而Array、 Set、Map、某些類別數組如arguments 等資料類型都預設提供了Iterator 接口,所以它們可以使用for-of 來進行遍歷。

而對於普通的對象,for...of結構不能直接使用,會報錯,提示obj is not iterable,也就是說普通對象預設沒有Iterator接口,必須部署了Iterator 介面後才能使用。

怎麼解決?讓for-of 遍歷物件

那麼原因清楚了,該怎麼解決呢?能不能為物件已經其它的一些資料型別提供Iterator 介面呢

答案是可以的,ES6 同時提供了Symbol.iterator 屬性,只要一個資料結構有這個屬性,就會被視為有Iterator 介面,接著就是如何實現這個介面了,如下就是一個最簡實作:

newObj[Symbol.iterator] = function(){
    let index = 0
        , self = this
        , keys = Object.keys( self )
        ;
    
    return {
        next(){
            if( index < keys.length ){
                return {
                    value: self[keys[index++]]
                    , done: false
                };
            }
            else{
                return {
                    value: undefined
                    , done: true
                }
            }
        }
    };
};

仔細看一下發現就會發現 Symbol.iterator 介面其實是一個 Generator 函數,那麼就可以簡化程式碼:

newObj[Symbol.iterator] = function* (){
    let keys = Object.keys( this )
        ;
    
    for(let i = 0, l = keys.length; i < l; i++){
        yield this[keys[i]];
    }
}

for(let v of newObj){
    console.log( v );
}
// 输出结果
// 5
// 6

值得注意的是 Object.keys 碰巧解決了先前 for-in 遇到的繼承問題

這樣滿足了我們的期望,使用 for-of 來遍歷對象,但是好像哪裡不對,我們遍歷對象時一般都是期望同時輸出 key 和 value 的,這樣調整程式碼

newObj[Symbol.iterator] = function* (){
    let keys = Object.keys( this )
        ;
    
    for(let i = 0, l = keys.length; i < l; i++){
        yield {
            key: keys[i]
            , value: this[keys[i]]
        };
    }
}

for(let v of newObj){
    console.log( v );
}
// 输出结果
// {key: "e", value: 5}
// {key: "f", value: 6}

這樣回傳了一個對象,似乎又很不舒服,我們能不能嘗試一些解構賦值呢。 。 。

for(let {key, value} of newObj){
    console.log(key, value );
}
// 输出结果
// e 5
// f 6

這樣似乎非常完美了。 。 。

擴充知識:for-of和其他迴圈的差異

#迴圈名稱 迴圈物件 是否可中斷迴圈 是否有回傳值
for for循環體的length 可以 無回傳值
forEach 僅可循環陣列、map、set等,不可循環字串、普通物件 不可以 無回傳值
do...while 滿足某種條件,則可一直循環,至少循環一次 可以 無回傳值
while #滿足某種條件,則可一直循環 可以 無回傳值
map 組成新的陣列成員,僅可循環數組,不可循環字串、普通對象,set 、map 不可中斷 傳回新數組,不影響原始數組
filter 過濾數組成員,僅可循環數組,不可循環字串、普通對象,set、map 不可中斷 傳回新數組,不影響原始數組
for...in 可循環陣列、物件,不可循環map、set。可遍歷數字鍵名,還可遍歷手動添加的其他鍵,甚至包括原型鏈上的鍵 可以 無回傳值
for...of 循環可迭代的對象,不可循環普通對象(統一資料結構遍歷) 可以 無回傳值

【相關推薦:javascript影片教學web前端

以上是es6的for of可以遍歷對象嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
React中的鑰匙:深入研究性能優化技術React中的鑰匙:深入研究性能優化技術May 01, 2025 am 12:25 AM

KeysinreactarecrucialforopTimizingPerformanceByingIneFefitedListupDates.1)useKeyStoIndentifyAndTrackListelements.2)避免使用ArrayIndi​​cesasKeystopreventperformansissues.3)ChooSestableIdentifierslikeIdentifierSlikeItem.idtomaintainAinainCommaintOnconMaintOmentStateAteanDimpperperFermerfermperfermerformperfermerformfermerformfermerformfermerment.ChosestopReventPerformissues.3)

反應中的鍵是什麼?反應中的鍵是什麼?May 01, 2025 am 12:25 AM

ReactKeySareUniqueIdentifiers usedwhenrenderingListstoimprovereConciliation效率。 1)heelPreactrackChangesInListItems,2)使用StableanDuniqueIdentifiersLikeItifiersLikeItemidSisRecumended,3)避免使用ArrayIndi​​cesaskeyindicesaskeystopreventopReventOpReventSissUseSuseSuseWithReRefers和4)

反應中獨特鍵的重要性:避免常見的陷阱反應中獨特鍵的重要性:避免常見的陷阱May 01, 2025 am 12:19 AM

獨特的keysarecrucialinreactforoptimizingRendering和MaintainingComponentStateTegrity.1)useanaturalAlaluniqueIdentifierFromyourDataiFabable.2)ifnonaturalalientedifierexistsistsists,generateauniqueKeyniqueKeyKeyLiquekeyperaliqeyAliqueLiqueAlighatiSaliqueLiberaryLlikikeuuId.3)deversearrayIndi​​ceSaskeyseSecialIndiceSeasseAsialIndiceAseAsialIndiceAsiall

將索引用作react中的鍵將索引用作react中的鍵May 01, 2025 am 12:17 AM

使用索引作為鍵在React中是可以接受的,但僅限於列表項順序不變且不會動態添加或刪除的情況;否則,應使用穩定且唯一的標識符作為鍵。 1)在靜態列表(如下拉菜單選項)中使用索引作為鍵是可以的。 2)如果列表項可以重新排序、添加或刪除,使用索引會導致狀態丟失和意外行為。 3)始終使用數據的唯一ID或生成的標識符(如UUID)作為鍵,以確保React正確更新DOM和維護組件狀態。

React的JSX語法:對UI設計的開發人員友好方法React的JSX語法:對UI設計的開發人員友好方法May 01, 2025 am 12:13 AM

jsxisspecialbecialbecapeitblendshtmlwithjavascript,enableComponent-lase-uidesign.1)itallowsembeddingjavascriptInhtml-likesyntax,EnhancinguidesignAndLogicIntegration.2)

使用HTML5可以播放哪種類型的音頻文件?使用HTML5可以播放哪種類型的音頻文件?Apr 30, 2025 pm 02:59 PM

本文討論了HTML5音頻格式和跨瀏覽器兼容性。它涵蓋MP3,WAV,OGG,AAC和WebM,並建議使用多個來源和後備以實現更廣泛的可訪問性。

SVG和Canvas HTML5元素之間的區別?SVG和Canvas HTML5元素之間的區別?Apr 30, 2025 pm 02:58 PM

SVG和畫布是Web圖形的HTML5元素。基於向量的SVG擅長可擴展性和交互性,而基於像素的畫布則更適合遊戲等性能密集型應用程序。

使用HTML5可能會拖放嗎?使用HTML5可能會拖放嗎?Apr 30, 2025 pm 02:57 PM

HTML5可以通過特定的事件和屬性進行拖放,從而允許自定義,但面臨舊版本和移動設備上的瀏覽器兼容性問題。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具