标签:
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个参数,
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); });
在浏览器打开,然后控制台就会看到有正确的输出了。
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的源码。
标签:
原文地址:http://www.cnblogs.com/yugege/p/5584672.html