4、迭代器模式

迭代器代理

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。

迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素。

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
 })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值