迭代器代理
迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。
迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。
jQuery中的迭代器
比如jQuery中的$.each函数,其中回调函数中的参数i为当前索引,n为当前元素。
$.each([1,2,3],function(i,n){
console.log('当前下标为:'+i);
console.log('当前值:'+n);
})
实现自己的迭代器
实现each函数,each函数接受2个参数,第一个为被循环的数组,第二个为循环中的每一步后将被触发的回调函数:
var each = function(ary,callback){
for(var i = 0,l = ary.length;i<l;i++){
callback.call(arr[i],i,ary[i])
}
}
each([1,2,3],function(i,n){
alert([i,n])
})
内部迭代和外部迭代器
内部迭代器
内部迭代器已经定义好了迭代规则,完全接手整个迭代过程,外部只需要一次初始调用。
上面的each函数就是内部迭代器
外部迭代器
外部迭代器必须显示地请求迭代下一个元素。
外部迭代器增加了一些调用的复杂度,但相对也增强了迭代器的灵活性,可以手工控制迭代的过程或者顺序。
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
}
}
再看看如何改写compare函数:
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相等')
}
var iterator1 = Iterator([1,2,3])
var iterator2 = Iterator([1,2,3])
compare(iterator1,iterator2) // 输出:iterator1 和 iterator2相等
外部迭代器虽然调用方式相对复杂,但适用性更广,能满足更多变的需求
内部迭代器和外部迭代器在实际生产中没有优劣之分,究竟使用哪个要根据需求场景定
迭代类数组对象和字面量对象
迭代器模式不仅可以迭代数组,还可以迭代一些类数组的对象。
比如 arguments、{"0":'a',"1":'b'}等,只要被迭代的聚合对象拥有length属性而且可以用下标访问,就可以被迭代。
倒序迭代器
var reverseEach = function(ary,callback){
for(var l = ary.length-1;l>=0;l--){
callback(l,ary[l])
}
}
reverseEach([0,1,2],function(i,n){
console.log(n);// 分别输出:2,1,0
})
中止迭代器
迭代器可以像普通for循环中的break一样,提供一种跳出循环的方法。
var each = function(ary,callback){
for(var i = 0,l=ary.length;i<l;i++){
if(callback(i,ary[i])==false){
break;
}
}
}
each([1,2,3,4,5],function(i,n){
if(n>3){ // n大于3的时候终止循环
return false;
}
console.log(n) // 分别输出:1,2,3
})
215

被折叠的 条评论
为什么被折叠?



