数组、对象迭代器

前端的朋友应该都用过一些迭代器,比如jQuery中的$.each()或underscore中的_.each();今天我们就来自己实现一个简单的迭代器:

我们仿照一些JS库的接口风格:each(arrOrObj, function(){})

 1 var each = function(obj, fn){
 2          var len = obj.length,i = 0;
 3          if( typeof(len) == ‘undefined‘ ){
 4                  //如果是对象 ,对象没有length属性
 5                  for( i in obj ){
 6                     if(false === fn.call(obj[i], obj[i], i)){break;}
 7                  }
 8          }
 9          else{
10             //如果是数组
11                 for(; i<len; i++){
12                    if ( false === fn.call(obj[i],i+1,obj[i]) ){
13                       break;
14                    }
15                 }
16          }
17 };

我们来分析一下,首先我们要判断需要迭代的是对象还是数组,是对象,就遍历每一个属性,是数组就遍历每一个数组的值。

数组和对象的区别在于数组有长度,对象没有长度。我们可以通过这一点来判断。

接下来是分别处理这两种情况:如果是对象,就要遍历每一个属性,我们打开调试器做一个小实验:

1 var obj = {‘a‘:1,‘b‘:2,‘c‘:3}
2 3 for(i in obj){console.log(‘i:  ‘,i,‘   v: ‘, obj[i]);}
4 i:   a    v:  1 
5 i:   b    v:  2 
6 i:   c    v:  3 

看来我们可以用for来遍历对象,接下来就是将遍历出来的结果传递到迭代器的回调函数中。

为了确保上下文关系,我们用call的方法调用回调函数,fn.call(obj[i], obj[i], i);

那么如果是数组呢:我们已经有了长度,就直接遍历;此时问题来了,原生的for循环中我们可以利用continue和break来控制循环,现在有该怎么实现呢?

我们可以利用回调函数的返回值来实现同样的效果:true、false。

这样我们就简单的实现了一个迭代器,考虑到实际项目中,我们还是使用一些比较成熟的js库,原因是这些js库的迭代器比较稳定,而且还提供了丰富的功能:

比如underscore

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。