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 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)
// 1
// 2
// 3
}
也可以給一個物件部署 Symbol.iterator屬性。
等這週五週六再總結一片文章。