理解 es6 的 Iterator
阿新 • • 發佈:2019-02-19
對於 Set
、Map
、Array
、String
等資料結構,我們希望有一種統一的方式可以遍歷其中的元素。
es6 給所有可以 遍歷 的資料結構賦予了一個統一的遍歷方法 for...of
。於是可以這樣:
const arr = ['hello', 'world']
for (let itm of arr) {
console.log(itm)
}
// string
const str = 'hello world'
for (let s of str) {
console.log(s)
}
而 for...of
這種方式,實際上就隱式呼叫了 Iterator 的方法。
Iterator 有什麼特性?
遍歷器具有 next 方法,它返回一個物件,反映 當前元素 和 當前狀態
iterator.next() // { value: current_element, done: false }
在
for...of
這種遍歷方式裡,實際就是通過不斷調iterator.next()
並判斷!done
來結束迴圈的。一個資料結構,只要它具有
Symbol.iterator
屬性,就可用for...of
遍歷。Symbol.iterator
實際是一個遍歷器生成函式,在for...of
中被自動呼叫
const arr = ['hello', 'world'
- 自定義的資料結構,可賦予
Symbol.iterator
屬性,這樣就可用for...of
遍歷它
const
下面再來定義一種新的資料結構:
Fibonacci
,給它賦予Symbol.iterator
屬性,以便用for...of
遍歷:class Fibonacci { constructor (number = 2) { this.n1 = 0 this.n2 = 1 this.number = number this.current = 0 } [Symbol.iterator] () { return this } next () { [this.n1, this.n2] = [this.n2, this.n1 + this.n2] let done this.current++ if (this.current > this.number) { done = true } else { done = false } return { value: this.n1, done } } }
用
new Fibonacci(10)
生成一個包含fibonacci
數列前 10 項的數列:const iter = new Fib(10) for (let itm of iter) { console.log(itm) // 1 1 2 3 5 8 13 21 34 55 }
哪些地方用到了 Iterator?
for...of
- 解構賦值
let set = new Set().add('a').add('b').add('c')
let [x, y] = set // a b
- 擴充套件運算子
...
[...'hello'] // ["h", "e", "l", "l", "o"]
// 沒錯,這個結果和 'hello'.split('') 的效果是一樣的
- generator
const gen = function* () {
yield 'hello'
yield 'world'
}
const gener = gen() // 得到了一個遍歷器(在 generator 概念中叫 生成器)
for (let i of gener) {
console.log(i)
}
還有其他的場合也用到了 Iterator,具體可參考阮一峰老師的《ES6 標準入門》