迭代器模式提供一種方法按順序存取一個聚合物件中的各個元素,而又不暴露該物件的內部表示。迭代器模式是目的性極強的模式
,它主要是用來解決遍歷問題。
JS原生的集合型別資料結構,有Array(陣列)和Object(物件),在ES6中,又新增了Map和Set。四種資料結構各自有著自己的內部實現,但對於使用者,我們希望以同樣的一套規則去遍歷它們,所以ES6在推出新資料結構的同時也推出了一套統一的介面機制——迭代器(Iterator)
。
Symbol.iterator
屬性(這個屬性就是Iterator的具體實現,它本質上是當前資料結構預設的迭代器生成函數),就可以被遍歷
,確切的說是被for...of...迴圈和迭代器的next方法遍歷,for...of...的背後正是對next方法的反覆呼叫。在ES6中,針對Array、Map、Set、String、TypedArray、函數的 arguments 物件、NodeList 物件這些原生的資料結構都可以通過for...of...進行遍歷。
迭代就是不斷的去拿下一個值的一個過程,以及遍歷完的狀態,是否完成遍歷。
// 定義生成器函數,入參是任意集合
function iteratorGenerator(list) {
// idx記錄當前存取的索引
let idx = 0
// len記錄傳入集合的長度
let len = list.length
return {
// 自定義next方法
next: function() {
// 如果索引還沒有超出集合長度,done為false
let done = idx >= len
// 如果done為false,則可以繼續取值
let value = !done ? list[idx++] : undefined
// 將當前值與遍歷是否完畢(done)返回
return {
done: done,
value: value
}
}
}
}
let iterator = iteratorGenerator(['1號選手', '2號選手', '3號選手'])
iterator.next()
iterator.next()
iterator.next()
在es6 中生成器函數
function * xxx 可以返回生成器物件( Generator 物件由生成器函數返回並且它符合可迭代協定和迭代器協定。)
生成器函數在執行時能暫停,後面又能從暫停處繼續執行。
// 生成器函數寫法
function* iteratorGenerator1(list) {
yield '生成器函數,我是1號'
yield '生成器函數,我是2號'
yield '生成器函數,我是3號'
}
let iterator1 = iteratorGenerator1()
console.log(iterator1.next())
console.log(iterator1.next())
console.log(iterator1.next())
// 生成器函數寫法--優化
function* iteratorGenerator2(list) {
let index = 0, len = list.length;
while (index <= len - 1) {
yield list[index]
index++
}
}
let iterator2 = iteratorGenerator2(['生成器函數優化,我是1號', '生成器函數優化,我是2號', '生成器函數優化,我說3號'])
console.log(iterator2.next())
console.log(iterator2.next())
console.log(iterator2.next())
可迭代協定:具備Symbol.iterator
迭代器協定:一個類似這個結構的物件:
{
next: function () {
return {
value: 'xx', // 當前遍歷節點的值
done: false // 是否完成遍歷
}
}
}
參考迭代協定