JavaScript:for in 和 for of的區別詳解

例1

    const obj = {
        a: 1,
        b: 2,
        c: 3
    }
    for (let i in obj) {
        console.log(i)
        // a
        // b
        // c
    }
    for (let i of obj) {
        console.log(i)
        // Uncaught TypeError: obj is not iterable 報錯了
    }

以上代碼通過 for in 和 for of 對一個obj對象進行遍歷,for in 正常的獲取了對象的 key值,分別打印 a、b、c,而 for of卻報錯了。

例2:

以上是遍歷對象,下面再看一個遍歷數組的例子。

    const arr = ['a', 'b', 'c']
    // for in 循環
    for (let i in arr) {
        console.log(i)
        // 0
        // 1
        // 2
    }
    
    // for of
    for (let i of arr) {
        console.log(i)
        // a
        // b
        // c
    }

以上代碼是對一個數組進行遍歷, for in 返回的值爲 0、1、2,這不是數組的下標嗎? 而 for of 返回的是 a、b、c,這一次沒有報錯,爲什麼呢?

例3

    const arr = ['a', 'b']
    // 手動給 arr數組添加一個屬性
    arr.name = 'qiqingfu'
    
    // for in 循環可以遍歷出 name 這個鍵名
    for (let i in arr) {
        console.log(i)
        // a
        // b
        // name
    }

for in 的特點

結合上面的兩個例子,分析得出:

  • for ... in 循環返回的值都是數據結構的 鍵值名
    遍歷對象返回的對象的key值,遍歷數組返回的數組的下標(key)。

  • for ... in 循環不僅可以遍歷數字鍵名,還會遍歷原型上的值和手動添加的其他鍵。如——例3

  • 特別情況下, for ... in 循環會以任意的順序遍歷鍵名

總結一句: for in 循環特別適合遍歷對象。

for of 特點

  • for of 循環用來獲取一對鍵值對中的,而 for in 獲取的是 鍵名

  • 一個數據結構只要部署了 Symbol.iterator 屬性, 就被視爲具有 iterator接口, 就可以使用 for of循環。
    例1這個對象,沒有 Symbol.iterator這個屬性,所以使用 for of會報 obj is not iterable

  • for of 不同與 forEach, 它可以與 break、continue和return 配合使用,也就是說 for of 循環可以隨時退出循環。

  • 提供了遍歷所有數據結構的統一接口

哪些數據結構部署了 Symbol.iteratoer屬性了呢?

只要有 iterator 接口的數據結構,都可以使用 for of循環。

  • 數組 Array
  • Map
  • Set
  • String
  • arguments對象
  • Nodelist對象, 就是獲取的dom列表集合

以上這些都可以直接使用 for of 循環。 凡是部署了 iterator 接口的數據結構也都可以使用數組的 擴展運算符(...)、和解構賦值等操作。

我也想讓對象可以使用 for of循環怎麼辦?

使用 Object.keys() 獲取對象的 key值集合後,再使用 for of

以例1爲例

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

    for (let i of Object.keys(obj)) {
        console.log(i)
        // a
        // b
        // c
    }

也可以給一個對象部署 Symbol.iterator屬性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章