本文以 用 for of
遍歷 Object
爲引 來聊聊 迭代器模式。
什麼是迭代器模式
迭代器模式提供一種方法順序訪問一個聚合對象中的各個元素,而又不暴露該對象的內部表示。 ——《設計模式:可複用面向對象軟件的基礎》
可以說迭代器模式就是爲了遍歷存在的。提到遍歷,大家都對那些手段耳熟能詳了,下面我們先簡單列一下各種數據類型的遍歷:
遍歷數組
-
for
循環 -
forEach
-
map
-
reduce
-
keys
-
values
-
for of
-
......
其中keys
values
for of
需要Iterator
支持,後面會介紹Iterator
遍歷 Map/Set
-
keys
-
entries
-
forEach
-
......
遍歷 Object
-
for in
-
先
Object.keys(obj)
得到對象每個屬性的數組, 然後使用數組的遍歷方法遍歷每個key
,就能獲取 每個key
對應的value
Iterator
和 for of
Iterator
是ES6提出的一個接口,爲各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署 Iterator
接口,就可以完成遍歷操作。
Iterator
的作用
-
爲各種數據結構,提供一個統一的、簡便的訪問接口。
-
ES6提出了新的遍歷命令
for...of
循環,Iterator
接口主要供for...of
消費。
Iterator
的遍歷過程
既然數組是支持for...of
循環的,那數組肯定部署了 Iterator
接口,我們通過它來看看Iterator
的遍歷過程。
從圖中我們能看出:
-
Iterator
接口返回了一個有next
方法的對象。 -
每調用一次 next,依次返回了數組中的項,直到它指向數據結構的結束位置。
-
返回的結果是一個對象,對象中包含了當前值
value
和 當前是否結束done
用 for of 遍歷 Object
回到標題中的問題,我們現在如何去讓一個對象也可以用 for of
來遍歷它呢?
根據上面講到的內容,需要給對象也部署 Iterator
接口(其實就是在Object.prototype
上實現一個以Symbol.iterator
爲名的function
,這個function
返回一個有next
方法的對象,每調用一次 next
, 能夠依次返回數組中的項,直到它指向數據結構的結束位置 )
function objectIterator() {
const keys = Object.keys(this)
let index = 0
return {
next: () => {
const done = index >= keys.length
const value = done ? undefined : this[keys[index]]
index++
return {
done,
value
}
}
}
}
Object.prototype[Symbol.iterator] = objectIterator
const obj = {
key: '1',
value: '2'
}
for (const iterator of obj) {
console.log(iterator)
}
[object Object]
更多精彩請點👉:開發者網站---面試問題