這篇文章只是聊一下iterator
的基礎知識, 如果想全面瞭解iterator
是什麼東西, 可以點這
一 . Iterator是什麼?
Iterator
是一個提供給各種資料結構訪問的統一介面, 簡單來說, iterator
就是一個介面
二 . Iterator有什麼用?
使用iterator
主要有三個作用
- 為一些資料結構
Map,Set,Array,String...
提供一個統一的簡便的訪問介面 - 使資料結構的成員按順序排序,可以通過
next
關鍵字按順序訪問資料結構的資料 - 供
for...of
遍歷消費 (主要)
三 . Iterator怎麼用? (重點來了)
重點在這 : 所有的遍歷器 iterator
都是從名為 [Symbol.iterator]
的介面(方法)開始出發的, 然後呼叫 next
方法按順序輸出資料
上面說到了 [Symbol.iterator]
next
, 那什麼是 [Symbol.iterator]
? 什麼是 next
?
- 什麼是
[Symbol.iterator]
[Symbol.iterator]
是啟動遍歷器的開關, 如果沒有這個開關, 就不存在遍歷器[Symbol.iterator]
分為先天的和後天的
首先, 先天的[Symbol.iterator]
存在在一些特殊的資料結構中, 包括 Array
String
Map
Set
TypedArray
arguments
NodeList(dom)
GeneratorObject
等等, 如下圖所示
看到沒, 就是這個東西, 在我說的那幾個資料結構中都有, 不信的可以自己一個一個去試試
但是, 不知道有沒有發現, 我們最常用的 Object
是沒有 [Symbol.iterator]
介面的
所以 Object
是不能使用 for...of
進行遍歷的
Object
有很多方法可以遍歷, 但是產品經理就要你用 for ... of
遍歷 Object
, 怎麼辦, 這就要說到後天的 [Symbol.iterator]
var obj = {
[Symbol.iterator] : () => {
return {}
}
}
for (const val of obj) {
console.log(val)
}
複製程式碼
Object
不是沒有 [Symbol.iterator]
方法嗎, 我們自己加一個不就行了
看 ! 現在 obj
是可遍歷的了 ( 這裡的錯誤先不管, 後面會說到 )
- 什麼是
next
上面說過 iterator
從 [Symbol.iterator]
開始, 通過 next
按順序輸出資料, 所以, 我們來看一下從 [Symbol.iterator]
出發後的是什麼東西
可以很清楚的看到, [Symbol.iterator]
執行後會返回一個包含 next
方法的物件
所以 , next
就是由 [Symbol.iterator]
執行後返回的一個方法, 下面我們來執行一下next
每次執行 next
都會返回一個物件 {value: xxx, done: xxx}
value
為遍歷的資料結構的每一位, done
表示是否完成遍歷
現在我們可以完善一下上面的錯誤了
var obj = {
[Symbol.iterator] : () => {
return {
next : () => {
const isContinue = (Math.random() > 0.75)
if (isContinue)
return {
value : `數字 ${Math.floor(Math.random() * 10)}`,
done : false
}
return { value : undefined, done : true}
}
}
}
}
for (const val of obj) {
console.log(val)
}
複製程式碼
ber ~ 這樣物件就算沒有 [Symbol.iterator]
介面也可以使用 for ... of
去遍歷了
- 什麼是
for ... of
一直在用 for ... of
, 順帶提一嘴, for ... of
是什麼玩意
for ... of
是ES6
的一個新遍歷的方法, 且只能遍歷具有 iterator
介面的資料結構, 也就是要有 [Symbol.iterator]
, 至於這個遍歷有什麼好處, 大家可自行百度一下
四 . 總結
所有的遍歷器 iterator
都是從名為 [Symbol.iterator]
的介面(方法)開始出發的, 然後呼叫 next
方法按順序輸出資料
ber~