迭代器模式
定义
迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。
JQuery中的迭代器
迭代器模式无非就是循环访问聚合对象中的各个元素。比如 jQuery 中的 $.each 函数,其中回调函数中的 index 为当前索引, value 为当前元素,代码如下:
$.each([1, 2, 3], function(index, value) {
console.log("当前下标为:" + index);
console.log("当前值为:" + value);
});
实现自己的迭代器
var Iterator = function(obj) {
var current = 0;
var next = function () {
var element;
if (!this.hasNext()) {
return null;
}
element = obj[current];
current += 1;
return element;
}
var hasNext = function() {
return current < obj.length;
}
var getCurrentItem = function () {
return obj[current];
}
return {
next: next,
hasNext: hasNext,
getCurrentItem: getCurrentItem,
length: obj.length,
}
}
var it = Iterator([1, 2, 3, 4, 5]);
while (it.hasNext()) {
console.log(it.next()); // 1, 2, 3, 4, 5
}
迭代类数组对象和字面量对象
迭代器模式不仅可以迭代数组,还可以迭代一些类数组的对象,例如 {“0” : “a”, “1” : “b”}。只要迭代的聚合对象拥有 length 属性而且可以用下标访问,那它就可以被迭代。
在 JavaScript 中, for in 语句可以用来迭代普通字面量对象的属性。jQuery 中提供了 $.each 函数来封装各种迭代行为:
$.each = function(obj, callback) {
var value,
i = 0,
length = obj.length,
isArray = isArraylike(obj);
if(isArray) {
for(; i < length; i++) {
value = callback.call(obj[i], i, obj[i]);
if(value === false) {
break;
}
}
} else {
for(i in obj) {
value = callback.call(obj[i], i, obj[i]);
if(value === false) {
break;
}
}
}
return obj;
}
中止迭代器
迭代器可以像普通 for 循环中的 break 一样,提供一种跳出循环的方法,即在传递的 callback 函数里返回 false, 则提前中止循环:
$.each([1, 2, 3], function(index, value) {
if(value > 2) {
return false;
}
console.log("当前下标为:" + index);
console.log("当前值为:" + value);
})
返回 true 则相当于 continue,则会跳过本次执行,继续后面的执行。
总结
迭代器模式是一种相对简单的模式,简单到很多时候我们都不认为它是一种设计模式。目前的绝大部分语言都内置了迭代器。