定義 迭代器模式提供一種方法按順序訪問一個聚合對象中的各個元素,而又不暴露該對象的內部表示。迭代器模式是目的性極強的模式,它主要是用來解決遍歷問題。 es6 中的迭代器 JS原生的集合類型數據結構,有Array(數組)和Object(對象),在ES6中,又新增了Map和Set。四種數據結構各自有著自 ...
定義
迭代器模式提供一種方法按順序訪問一個聚合對象中的各個元素,而又不暴露該對象的內部表示。迭代器模式是目的性極強的模式
,它主要是用來解決遍歷問題。
es6 中的迭代器
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()
generator 寫法
在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 // 是否完成遍歷
}
}
}
參考迭代協議
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/function*