迭代器模式的概念
1、迭代器模式号称“遍历专家”,它提供一种方法顺序访问一个聚合对象中的各个元素,且不暴露该对象的内部表示。
2、迭代器又分 2 类
1、内部迭代器( jquery.each / for...of )
2、外部迭代器( es6 yield )
3、在 es6 之前,直接通过 forEach 遍历 DOM NodeList 和函数的 arguments 对象,都会直接报错,其原因都是因为他们都是类数组对象。对此 jquery 很好的兼容了这一点。
4、在 es6 中,它约定只要数据类型具备 Symbol.iterator 属性,就可以被 for...of 循环和迭代器的 next 方法遍历。
迭代器模式的例子
1、Array.prototype.forEach
2、jQuery中的 $.each()
3、ES6 Iterator
迭代器模式的代码示例
class Iterator {
constructor(conatiner) {
this.list = conatiner.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
}
}
class Container {
constructor(list) {
this.list = list
}
getIterator() {
return new Iterator(this)
}
}
// 测试代码
let container = new Container([1, 2, 3, 4, 5])
let iterator = container.getIterator()
while(iterator.hasNext()) {
console.log(iterator.next())
}
(function (a, b, c) {
const arg = arguments;
const iterator = arg[Symbol.iterator]();
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
})(1, 2, 3)
通过 es6 内置生成器 Generator 实现迭代器并没什么难度,这里重点通 es5 实现迭代器
function iteratorGenerator (list) {
var index = 0;
// len 记录传入集合的长度
var len = list.length;
return {
// 自定义 next 方法
next: funciton () {
// 如果索引还没有超出集合长度,done 为 false
var done = index >= len;
// 如果 done 为 false,则可以继续取值
var value = !done ? list[index++] : undefined;
// 将当前值与遍历是否完毕(done)返回
return {
done: done,
value: value
};
}
}
}
var iterator = iteratorGenerator([1, 2, 3]);
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
迭代器模式的总结
小结
实现统一遍历接口,符合单一功能和开放封闭原则。
使用场景
有遍历的地方就有迭代器。
对于集合内部结果常常变化各异,不想暴露其内部结构的话,但又想让客户代码透明的访问其中的元素,可以使用迭代器模式
特点
1、访问一个聚合对象的内容而无需暴露它的内部表示。
2、为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作