用过Underscore的朋友都知道,它对数组(集合)的遍历有着非常完善的API可以调用的,_.each()就是其中一个。下面就是一个简单的例子:
var arr = [1, 2, 3, 4, 5];
_.each(arr, function(el) {
console.log(el);
});

上面的代码会依次输出1, 2, 3, 4, 5,是不是很有意思,遍历一个数组连for循环都不用自己写了。_.each()方法遍历数组非常好用,但是它的内部实现一点都不难。下面就一起来看看到底是如何实现_.each()的。在这之前,我们先来看看_.each()的API。_.each()的一般是如下调用的:

_.each(arr, fn, context);

它接收3个参数,

第一个是需要遍历的数组(其实是对象也是可以的,这个后面我们再一起来讨论);
第二个是它的回调函数(这个回调函数可以传入3个参数,如:function(el, i, arr),分别是当前元素、当前索引和原数组);
第三个是回调函数需要绑定到的上下文,即指定回调函数fn的this值。
 
好啦,需求已经非常明确了,开始干活啦!
我们先来实现一个最简单的_.each(),它不能够修改上下文this的,接收两个参数,代码如下:
 
var _ = {}; // 假设这就是underscore哈

// 一个最简单的_.each方法的实现
_.each = function(arr, fn) {
  for(var i = 0; i < arr.length; i++) {
    fn(arr[i], i, arr);
  }
  return arr; // 把原数组返回
}

怎么样?是不是很简单呢?只是用一个for循环,不停的调用回调函数即可,短短几行代码就搞定了,相信没有朋友看不懂的哈!下面我们来测试一下看能不能正常工作:

var arr = [1, 2, 3, 4, 5];
_.each(arr, function(el, i, arr) {
  console.log(el);
});

在浏览器打开,然后控制台就会看到有正确的输出了。

这么简单的代码一点意思也没有,接下来看一个比较有点挑战性的例子哈。比如,数组arr有个sum属性,我们需要把数组所有的元素求和之后存放到sum里面,如下:
var arr = [1, 2, 3, 4, 5];
arr.sum = 0; // sum属性用来存放数组元素之和
_.each(arr, function(el, i, arr) {
  this.sum += el;
});

这时候,回调函数里面用到了this,如果不绑定的话,this默认就是window,这不是我们想要的,我们希望它绑定到数组arr上面。call或者apply可以实现这个功能,代码如下:

var _ = {}; // 假设这就是underscore哈

// bind,接收两个参数fn和context
// 把fn绑定到context上面
var bind = function(fn, context) {
  context = context || null;
  return function(el, i, arr) {
    fn.call(context, el, i, arr);
  }
} // _.each
_.each = function(arr, fn, context) {   // 调用bind方法,把fn绑定到context上面
  fn = bind(fn, context);   for(var i = 0; i < arr.length; i++) {
    fn(arr[i], i, arr);
  }
  return arr;
} // 测试用例:
var arr = [1, 2, 3, 4, 5];
arr.sum = 0; // sum属性用来存放数组元素之和 _.each(arr, function(el, i, arr) {
  this.sum += el;
}, arr); console.log(arr.sum); //

好啦,这个_.each()已经足够强大了,可以正常遍历数组,还可以任意指定this值改变回调函数的上下文。但是,我们前面有提到过,Underscore的_.each()还可以遍历对象的 ,这个实现也不难,只要判断一下传入的第一个参数是对象还是数组,如果是数组就像我们一样遍历,否则如果是对象,使用对象的for...in循环遍历就行了。有兴趣的可以自己试试,或者看看underscore的源码。

注意:自从ES5标准以来,原生数组就已经具有了Array.prototype.forEach、Array.prototype.Map等遍历方法了,在项目中可以使用原生的。
 
 
 

浅谈JS的数组遍历方法的更多相关文章

  1. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  2. 浅谈6种JS数组遍历方法的区别

    本篇文章给大家介绍一下6种JS数组遍历方法:for.foreach.for in.for of.. each. ().each的区别.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. ...

  3. 浅谈 js 字符串 trim 方法之正则篇

    原文:浅谈 js 字符串 trim 方法之正则篇 关于 trim 其实没啥好说的,无非就是去除首位空格,对于现代浏览器来说只是简单的正则 /^\s+|\s+$/ 就可以搞定了.而且支持中文空格   等 ...

  4. 浅谈 js 字符串 search 方法

    原文:浅谈 js 字符串 search 方法 这是一个很久以前的事情了,好像是安心兄弟在学习js的时候做的练习.具体记不清了,今天就来简单分析下 search 究竟是什么用的. 从字面意思理解,一个是 ...

  5. JS数组遍历方法

    常用数组遍历方法: 1.原始for循环 var a = [1,2,3]; for(var i=0;i<a.length;i++){ console.log(a[i]); //结果依次为1,2,3 ...

  6. js中数组遍历常用的方法

    常见的数组遍历方法,比如 for in,for  of, forEach,map,filter,every,some,find,reduce等 1,普通for循环,经常用的数组遍历 var arr = ...

  7. js数组遍历方法总结

    数组遍历方法 1.for循环 使用临时变量,将长度缓存起来,避免重复获取数组长度,当数组较大时优化效果才会比较明显. 1 2 3 for(j = 0,len=arr.length; j < le ...

  8. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  9. 浅谈JS之AJAX

    0x00:什么是Ajax? Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HT ...

随机推荐

  1. EXCEL中把两列表格里的数字合成一列并且中间用逗号隔开

    背景:使用loadrunner做参数化时,往往需要在excel表格中做数据,比如:第一列是用户名,第二列是密码,格式如下: 再将用户名和密码合并成一列,以逗号分隔,需要用到的公式为: =A1& ...

  2. windows2012安装

    windows server 2012 r2 安装无法找到install.wim 错误代码0x80070026,以及制作U启动盘决解ISO文件超过5G大小限制的解决方案关于在服务器上安装windows ...

  3. 『Python CoolBook:Collections』数据结构和算法_collections.deque队列&yield应用

    一.collections.deque队列 deque(maxlen=N)构造函数会新建一个固定大小的队列.当新的元素加入并且这个队列已满的时候,最老的元素会自动被移除掉. 如果你不设置最大队列大小, ...

  4. js的event事件对象汇总

    JavaScript事件对象是浏览器默认传入的,但是对于浏览器的兼容问题,我们需要对事件对象进行兼容.但是jQuery已经帮我们解决了所有兼容性的问题,并且给我们添加了很多有用的方法.已经是比较历史的 ...

  5. xml字符串,xml对象,数组之间的相互转化

    <?phpnamespace Home\Controller;use Think\Controller;class IndexController extends Controller { pu ...

  6. android中include

    android中include. include标签用法. 1.新建一个xml文件,命名 head.xml head.xml文件内容如下: <?xml version="1.0&quo ...

  7. 数据结构与算法之PHP排序算法(希尔排序)

    一.基本思想 希尔排序算法是希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接 ...

  8. Web 安全漏洞之 XSS 攻击

    什么是 XSS 攻击 XSS(Cross-Site Scripting)又称跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行.XSS是一种经常出现在 Web 应用程序中的计算机安全漏洞,是由于 ...

  9. liunx文件操作 文件压缩

    文件备份和压缩命令 在Linux中,常用的文件压缩工具有gzip,bzip2,zip. 'bzip2'是最理想的压缩工具,它提供了最大限度的压缩. 'zip'兼容好,windows也支持. bzip2 ...

  10. learning makefile manner of working