深入浅析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 相关文章推荐
静态页面下用javascript操作ACCESS数据库(读增改删)的代码
May 14 Javascript
理解JavaScript的caller,callee,call,apply
Apr 28 Javascript
jquery对dom的操作常用方法整理
Jun 25 Javascript
js/jquery去掉空格,回车,换行示例代码
Nov 05 Javascript
JavaScript 学习笔记之变量及其作用域
Jan 14 Javascript
node.js实现回调的方法示例
Mar 01 Javascript
vuex 项目结构目录及一些简单配置介绍
Apr 08 Javascript
JavaScript+H5实现微信摇一摇功能
May 23 Javascript
详解Vue中使用Echarts的两种方式
Jul 03 Javascript
ES6 如何改变JS内置行为的代理与反射
Feb 11 Javascript
使用Angular material主题定义自己的组件库的配色体系
Sep 04 Javascript
Vue Router中应用中间件的方法
Aug 06 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
yii框架表单模型使用及以数组形式提交表单数据示例
2014/04/30 PHP
Smarty模板简单配置与使用方法示例
2016/05/23 PHP
ASP.NET中使用后端代码注册脚本 生成JQUERY-EASYUI的界面错位的解决方法
2010/06/12 Javascript
基于JQuery的asp.net树实现代码
2010/11/30 Javascript
基于Arcgis for javascript实现百度地图ABCD marker的效果
2015/09/12 Javascript
理解javascript定时器中的单线程
2016/02/23 Javascript
JavaScript学习笔记之数组去重
2016/03/23 Javascript
基于cssSlidy.js插件实现响应式手机图片轮播效果
2016/08/30 Javascript
使用canvas进行图像编辑的实例
2017/08/29 Javascript
AngularJS 事件发布机制
2018/08/28 Javascript
Vue中JS动画与Velocity.js的结合使用
2019/02/13 Javascript
JavaScript数组去重的几种方法
2019/04/07 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
2019/08/27 Javascript
layui中的switch开关实现方法
2019/09/03 Javascript
vue实现购物车的监听
2020/04/20 Javascript
JS实现canvas简单小画板功能
2020/06/23 Javascript
js实现轮播图效果 纯js实现图片自动切换
2020/08/09 Javascript
[02:07]DOTA2超级联赛专访BBC:难忘网吧超神经历
2013/06/09 DOTA
[06:01]刀塔次级联赛top10第一期
2014/11/07 DOTA
python线程池的实现实例
2013/11/18 Python
Python标准库之循环器(itertools)介绍
2014/11/25 Python
Python实现周期性抓取网页内容的方法
2015/11/04 Python
详解设计模式中的工厂方法模式在Python程序中的运用
2016/03/02 Python
python魔法方法-属性转换和类的表示详解
2016/07/22 Python
Python贪心算法实例小结
2018/04/22 Python
python 获取一个值在某个区间的指定倍数的值方法
2018/11/12 Python
pytorch 改变tensor尺寸的实现
2020/01/03 Python
Sarenza德国:法国最大的时尚鞋和包包网上商店
2019/06/08 全球购物
瑞典多品牌连锁店:Johnells
2021/01/13 全球购物
Linux如何修改文件和文件夹的权限
2013/09/05 面试题
教师党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
教代会开幕词
2015/01/28 职场文书
党员干部公开承诺书范文
2015/04/27 职场文书
python 实现定时任务的四种方式
2021/04/01 Python
gateway网关接口请求的校验方式
2021/07/15 Java/Android
使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐)
2022/01/18 PostgreSQL