深入浅析JS的数组遍历方法(推荐)


Posted in Javascript onJune 15, 2016

用过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等遍历方法了,在项目中可以使用原生的。

以上所述是小编给大家介绍的深入浅析JS的数组遍历方法(推荐)的全部叙述,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js 全兼容可高亮二级缓冲折叠菜单
Jun 04 Javascript
jQuery中ajax的使用与缓存问题的解决方法
Dec 19 Javascript
基于JavaScript实现表单密码的隐藏和显示出来
Mar 02 Javascript
第十篇BootStrap轮播插件使用详解
Jun 21 Javascript
最全面的JS倒计时代码
Sep 17 Javascript
vuex实现简易计数器
Oct 27 Javascript
JS实现图片垂直居中显示小结
Dec 13 Javascript
js实现扫雷小程序的示例代码
Sep 27 Javascript
解决Linux无法正常安装与卸载Node.js的方法
Jan 19 Javascript
基于Vue 服务端Cookies删除的问题
Sep 21 Javascript
微信小程序之数据绑定原理解析
Aug 14 Javascript
mpvue微信小程序开发之实现一个弹幕评论
Nov 24 Javascript
JavaScript对象数组排序实例方法浅析
Jun 15 #Javascript
JavaScript实现点击文本自动定位到下拉框选中操作
Jun 15 #Javascript
JavaScript对象数组如何按指定属性和排序方向进行排序
Jun 15 #Javascript
jQuery动态加载css文件实现方法
Jun 15 #Javascript
异步加载JS、CSS代码(推荐)
Jun 15 #Javascript
全面解析Javascript无限添加QQ好友原理
Jun 15 #Javascript
漫谈JS引擎的运行机制 你应该知道什么
Jun 15 #Javascript
You might like
PHP+jQuery 注册模块的改进(三):更新到Smarty3.1
2014/10/14 PHP
nginx+thinkphp下解决不支持pathinfo模式
2015/07/01 PHP
PHP+AjaxForm异步带进度条上传文件实例代码
2017/08/14 PHP
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
javascript 事件绑定问题
2011/01/01 Javascript
JS控制日期显示的小例子
2013/11/23 Javascript
javascript写的异步加载js文件函数(支持数组传参)
2014/06/07 Javascript
使用jQuery实现图片遮罩半透明坠落遮挡
2015/03/16 Javascript
.NET微信公众号开发之创建自定义菜单
2015/07/16 Javascript
详述JavaScript实现继承的几种方式(推荐)
2016/03/22 Javascript
浅析BootStrap模态框的使用(经典)
2016/04/29 Javascript
jQuery的ajax和遍历数组json实例代码
2016/08/01 Javascript
使用Promise链式调用解决多个异步回调的问题
2017/01/15 Javascript
vue2.0父子组件及非父子组件之间的通信方法
2017/01/21 Javascript
jQuery实现优雅的弹窗效果(6)
2017/02/08 Javascript
一个简易时钟效果js实现代码
2020/03/25 Javascript
使用Ajax和Jquery配合数据库实现下拉框的二级联动的示例
2018/01/25 jQuery
webstorm中配置Eslint的两种方式及差异比较详解
2018/10/19 Javascript
vue计算属性get和set用法示例
2019/02/08 Javascript
angular2 NgModel模块的具体使用方法
2019/04/10 Javascript
微信小程序实现卡片层叠滑动效果
2019/06/21 Javascript
vant 时间选择器--开始时间和结束时间实例
2020/11/04 Javascript
vue3+typeScript穿梭框的实现示例
2020/12/29 Vue.js
用python实现的可以拷贝或剪切一个文件列表中的所有文件
2009/04/30 Python
Python基础之getpass模块详细介绍
2017/08/10 Python
对Pandas DataFrame缺失值的查找与填充示例讲解
2018/11/06 Python
python turtle工具绘制四叶草的实例分享
2020/02/14 Python
浅谈Python 函数式编程
2020/06/20 Python
安装Anaconda3及使用Jupyter的方法
2020/10/27 Python
夏洛特和乔治婴儿和儿童时装精品店:Charlotte and George
2018/06/06 全球购物
工商技校毕业生自荐信
2013/11/15 职场文书
上课打牌的检讨书
2014/02/15 职场文书
企业业务员岗位职责
2014/03/14 职场文书
出国英文推荐信
2014/05/10 职场文书
会计做账心得体会
2016/01/22 职场文书
基于Redis实现分布式锁的方法(lua脚本版)
2021/05/12 Redis