例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屬性。