迭代器模式
提供一种方法,顺序访问一个聚合对象中各个元素,而又无需暴露该对象的内部表示。
迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。
模拟一个迭代器对象
let arr = [1,2,3,4] // 数组集合1
let arr2 = ["一","二","三","四"] // 数组集合2
// 手写模拟一个迭代器
class Iterator{ // 迭代器类
constructor(list){ // 接收获取到的集合对象
this.list = list
this.index = 0 // 传入的集合对象中内容元素的下标
}
next(){ // 迭代器迭代下一个元素的方法
if(this.hasNext()){ // 有未被遍历的元素才继续遍历
return this.list[this.index++]
}
return null // 否则返回空,表示没有元素了
}
hasNext(){ // 判断该集合内是否还有写一个未被遍历的元素,如果有才能进行遍历
if(this.index >= this.list.length){ // 如果遍历的元素下标大于这个集合对象的内容长度,表明对象内所有元素都被遍历了,没有未遍历的
return false
}
return true // 否则返回true
}
}
let iter = new Iterator(arr) // 实例化迭代器对象,传入接收的集合
let iter1 = new Iterator(arr2)
// 每次要迭代时,就调用它的迭代方法,调用几次迭代几次
console.log(iter.next()) // 1
console.log(iter.next()) // 2
console.log(iter.next()) // 3
console.log(iter.next()) // 4
console.log(iter.next()) // null
// 用while循环来调用方法遍历
while(iter1.hasNext()){
console.log(iter1.next()) // 打印 一 二 三 四
}
使用ES6中的iterator封装一个遍历方法each
// 使用es6中的iterator方法手动封装一个遍历方法each
function each(list){
let iter = list[Symbol.iterator]() // list集合对象的Symbol方法返回一个函数,这个函数执行,使其返回一个迭代器给iter
let item = {done:false} // 写一个标识,默认为false,表示未遍历完成
while(!iter.done){ // 当还未遍历完成时
item = iter.next() // next方法是迭代器自带的方法
if(!item.done){
console.log(item.value)
}
}
}
let map = new Map() //实例生成一个对象map
map.set("a",1) //往map对象中创建键值对
map.set("b",2)
each(map) //each函数中传入map集合对象,就可以迭代
万章老师的迭代器模式代码
let obj = {
data: [ 'hello', 'world' ],
[Symbol.iterator]() {
const self = this;
let index = 0;
return {
next() {
if (index < self.data.length) {
return {
value: self.data[index++],
done: false
};
} else {
return { value: undefined, done: true };
}
}
};
}
};