1. 程式人生 > >for in 和 for of的區別詳解

for in 和 for of的區別詳解

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 infor 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)
        // 1
        // 2
        // 3
    }
也可以給一個物件部署 Symbol.iterator屬性。

等這週五週六再總結一片文章。