首页 > 代码库 > 数组、对象迭代器

数组、对象迭代器

前端的朋友应该都用过一些迭代器,比如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

 

数组、对象迭代器