用过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); // 15

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

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

转载于:https://www.cnblogs.com/yugege/p/5584672.html

浅谈JS的数组遍历方法相关推荐

  1. js 数组遍历方法详解(map、filter、find、findIndex、reduce)

    目录 前言 map map是什么 map方法的结构及入参 语法糖 map一般不改变原数组 filter 说明 例子 find 和 findIndex 说明 例子 reduce 说明 例子 尾言 前言 ...

  2. php字面量,浅谈js之字面量、对象字面量的访问、关键字in的用法

    一:字面量含义 字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量. 字面量分为字符串字面量(string literal ).数组字面量(array literal) ...

  3. ES5和ES6数组遍历方法详解

    ES5和ES6数组遍历方法详解 在ES5中常用的10种数组遍历方法: 1.原始的for循环语句 2.Array.prototype.forEach数组对象内置方法 3.Array.prototype. ...

  4. php 合并数组对象,JS内数组合并方法与对象合并实现步骤详解

    这次给大家带来JS内数组合并方法与对象合并实现步骤详解,JS内数组合并方法与对象合并实现的注意事项有哪些,下面就是实战案例,一起来看一下. 1 数组合并 1.1 concat 方法var a=[1,2 ...

  5. js中数组map方法的使用和实现

    js中数组map方法的使用和实现 MDN中定义 map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值. 语法 var new_array = arr.map(fun ...

  6. 浅谈JS中常见的问题(三)

    往期文章目录 浅谈JS中常见的问题(一) 浅谈JS中常见的问题(二) JS知识总结 往期文章目录 前言 11. 同步和异步的区别 12. JS 判断变量类型的几种方法 13. 如何阻止事件冒泡与默认事 ...

  7. php的遍历方法,PHP数组遍历方法总结

    在PHP中数组分为两类: 数字索引数组和关联数组. 其中数字索引数组和C语言中的数组一样,下标是为0,1,2- 而关联数组下标可能是任意类型,与其它语言中的hash,map等结构相似. 下面介绍PHP ...

  8. 必看!清华大学刘洋教授“浅谈研究生学位论文选题”方法,3月7日1小时视频公开课(附视频PPT下载)...

    来源:专知 本文约700字,建议阅读5分钟 清华大学计算机系长聘教授刘洋老师在线讲授了关于<浅谈研究生学位论文选题方法>的课程. 标签:论文研究方法 [ 导读 ]在继续抗击疫情之际,3月7 ...

  9. 【强烈推荐】清华大学刘洋老师【浅谈研究生学位论文选题方法】讲座

    关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 在继续抗击疫情之际,3月7日,清华大学计算机系长聘教授刘洋老师在线讲授了关于< ...

最新文章

  1. 2016年十大存储预测
  2. 我的世界基岩版json_我的世界基岩版合集
  3. Hadoop 中zoo_0基础如何入门HADOOP
  4. 如何将二维数组作为函数的参数传递
  5. Python int函数 - Python零基础入门教程
  6. PHP文字转语音合成网源码 百度API开发
  7. OSChina 周五乱弹 —— 你专业是啥,被叫去搬砖了吗?
  8. 基于android的视频播放器,基于Android的视频播放器的设计与实现-.doc
  9. 腾讯 WXG | 技术研究-NLP算法三面复盘
  10. Log4j 2.x使用遇到的问题
  11. 空降项目经理,该如何服众?
  12. matlab——整数规划
  13. 正厚软件 | 为什么要转行IT?
  14. 公司/企业如何管理?管理技巧是什么?《宁向东管理学课》音频资料免费下载
  15. pandas使用read_csv函数读取文件的前N行数据并保留表头、pandas使用read_csv函数读取制表符分割的文件(tab-delimited)、自定义设置sep参数
  16. 头歌:《C语言程序设计编程实践任务》教学团队:祁文青:选择结构程序设计
  17. csdn最详细最牛逼的 阿里最新app自动化测试---自动化测试框架搭建
  18. $Loj10155$ 数字转换(求树的最长链) 树形$DP$
  19. QTransform(图形平移旋转剪切变换)
  20. listview(retrofit)

热门文章

  1. 想与 Oracle 说“再见”,太难了!
  2. Netty解决粘包和拆包问题的四种方案
  3. 秒杀系统流量削峰,这事应该怎么做?
  4. 为什么 Java 线程没有 Running 状态?
  5. 一文搞懂 Java 泛型,非常详细!
  6. Java 并发框架全览,这个牛逼!
  7. Android——怎么在一个 Activity 中销毁另外一个 Activity
  8. Java 洛谷 P1085 不高兴的津津
  9. 在tomcat上部署项目,实现类似添加这样的功能之后,tomcat要运行很久,解决办法
  10. Linux通常把设备对象抽象为,linux 设备模型(1)