一、介绍
定义:
迭代器模式是一种行为设计模式, 让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。
个人理解:
在JavaScript的已经内置了迭代器。Array,Map就是可迭代对象,内部实现了@@iterator,也就是 Symbol.iterator 。
主要解决:
不同的方式来遍历整个整合对象。
如何解决:
将集合的遍历行为抽取为单独的迭代器对象。
关键代码:
遍历算法的封装。
应用实例:
- Array
- Map
使用场景:
- 以减少程序中重复的遍历代码。
- 隐藏遍历的复杂代码。
优点:
- 单一职责原则。 通过将体积庞大的遍历算法代码抽取为独立的类, 你可对客户端代码和集合进行整理。
- 开 闭 原 则。 你可实现新型的集合和迭代器并将其传递给现有代码, 无需修改现有代码。
- 你可以并行遍历同一集合, 因为每个迭代器对象都包含其自身的遍历状态。
- 相似的, 你可以暂停遍历并在需要时继续。
缺点:
-
如果你的程序只与简单的集合进行交互, 应用该模式可能会矫枉过正。
-
对于某些特殊集合, 使用迭代器可能比直接遍历的效率低。
二、内部迭代器
定义:一个函数内部定义好遍历算法,它完全接口整个迭代过程,外部只需要一次初始化调用。
由于是内部定义,遍历算法无法修改,缺少灵活性。
var each = function (ary, callback) {
for (var i = 0, l = ary.length; i < l; i++) {
callback.call(ary[i], i, ary[i]); // 把下标和元素当作参数传给callback函数
}
};
each([1, 2, 3], function (i, n) {
alert([i, n]);
});
三、外部迭代器
定义:一个函数封装迭代的规则,接收一个对象,返回一个迭代器(对象,有next的方法,参考迭代器协议)。
var Iterator = function (obj) {
var current = 0;
var next = function () {
current += 1;
};
var isDone = function () {
return current >= obj.length;
};
var getCurrItem = function () {
return obj[current];
};
return {
next: next,
isDone: isDone,
getCurrItem: getCurrItem,
length: obj.length
}
};
var compare = function (iterator1, iterator2) {
if (iterator1.length !== iterator2.length) {
alert('iterator1和iterator2不相等');
}
while (!iterator1.isDone() && !iterator2.isDone()) {
if (iterator1.getCurrItem() !== iterator2.getCurrItem()) {
throw new Error('iterator1和iterator2不相等');
}
iterator1.next();
iterator2.next();
}
alert('iterator1和iterator2相等');
}
compare(Iterator([1, 2, 3]), Iterator([1, 2, 4]))
四、拓展
迭代器模式
迭代器
在JavaScript中,迭代器是一个对象,内部通过next方法实现了迭代器协议。next方法返回一个对象,{done:boolean,value:''}
{
done:false,
value:1
}
{
done:true
}
迭代器和生成器 - JavaScript | MDN (mozilla.org)
迭代协议
迭代协议 - JavaScript | MDN (mozilla.org)