一、迭代器模式概念
- 顺序遍历【有序】集合
- 使用者无需知道集合的内部结构
二、UML类图
传统UML类图
简化后的UML类图
迭代器类代码实现
三、使用场景
1、jQuery each
如果要遍历【数组、NodeList、jQuery对象集合】,分别要使用三种方式遍历
但是如果使用jQuery转成JQuery对象集合(迭代器),则可以直接使用jQuery each遍历
2、ES6 Iterator
ES6语法中的【有序】集合数据类型有:Array、String、arguments、NodeList、Map、Set、TypedArray。(注意:object不是有序集合,可以用Map代替)
- 以上数据类型都有[Symbol.iterator]属性。属性值是函数,执行函数返回一个迭代器
- 这个迭代器有next方法可顺序迭代子元素
根据以上特点,我们可以重写遍历方法如下:
function each(data) {
// 生成迭代器
let iterator = data[Symbol.iterator]()
// 初始化一个迭代结果
let item = {done: false}
// 循环迭代成员
while (!item.done) {
item = iterator.next()
if (!item.done) {
console.log(item.value)
}
}
}
- 实际我们平时遍历一个有序集合并不需要自己封装一个以上的方法,其实ES6已经有了针对可迭代对象的遍历方法(for/of)。
- 注:for/of循环要求of后面必须是【可迭代对象】,for/in循环的in后面可以是任意对象。
用ES5去写一个能够生成迭代器对象的迭代器生成函数
// 定义生成器函数,入参是任意集合
function iteratorGenerator(list) {
// idx记录当前访问的索引
var idx = 0
// len记录传入集合的长度
var len = list.length
return {
// 自定义next方法
next: function() {
// 如果索引还没有超出集合长度,done为false
var done = idx >= len
// 如果done为false,则可以继续取值
var value = !done ? list[idx++] : undefined
// 将当前值与遍历是否完毕(done)返回
return {
done: done,
value: value
}
}
}
}
var iterator = iteratorGenerator(['1号选手', '2号选手', '3号选手'])
iterator.next()
iterator.next()
iterator.next()
Generator
除了以上数据类型以外,Generator函数返回结果,也可实现Iterator接口。(Generator 已被async/await取代)