Prototype源码浅析 Enumerable部分之each方法


Posted in Javascript onJanuary 16, 2012

在javascript中,根本找不到Enumerable的影子,因为这一块是Prototype作者从Ruby中借鉴过来的。并且Enumerable在实际中根本没有直接应用的机会,都是混入到其他的对象中,可以说是其他对象的一个“父类”(不过只是调用了Object的extend方法,进行了方法的直接拷贝而已)。

我并不熟悉Ruby,不过看Enumerable中的一些方法,倒是跟Python中的有几分相似。

Enumerable其中一个最重要的方法是each,each这个方法应该都比较熟悉,其作用便是遍历一个序列的所有元素,并进行相应的处理。不过多数是应用在数组上,比如原生数组的forEach方法,以及jQuery中的链式调用,都依赖于each方法。因为jQuery选择器返回的是一个DOM对象数组,然后再在返回的数组上来调用each,从而分别处理每一个元素。

一般each都有两个参数:一个是迭代处理的函数和方法对应的上下文。

var each = Array.prototype.forEach || function(iterator,context){ 
for(var i = 0,len = this.length ; i < len ; i++){ 
iterator.call(context,this[i],this); 
} 
};

按照上面的方法,我们给Array对象扩展一个打印当前所有元素的print方法。

Array.prototype.each = Array.prototype.forEach || function(iterator,context){ 
for(var i = 0,len = this.length ; i < len ; i++){ 
iterator.call(context,this[i],i,this); 
} 
}; 
Array.prototype.print = function(){ 
this.each(function(item){ 
console.log(item); 
}); 
} 
console.log([1,2,3,4].print());//1,2,3,4

在Enumerable中,each并没有对应到具体的方法,前面说过Enumerable并不之际应用,而是作为一个“父类”应用到其他的对象,因此它的each方法是调用“子类”_each方法,因此任何混入Enumerable模块的对象,都必须提供一个_each方法,作为作用于实际循环的迭代代码。

现在Array.prototype上实现一个_each方法和一个each方法,实现一:

Array.prototype.each = function(iterator,context){ 
this._each(iterator,context) 
} 
Array.prototype._each = function(iterator,context){ 
for(var i = 0,len = this.length ; i < len ; i++){ 
iterator.call(context,this[i],i,this); 
} 
};

按照先前说的,_each只需要提供一个iterator参数就可以了,不过由于_each也被扩展到Array.prototype上面,于是实现的时候也附带了context参数。因此在Enumerable中,并没有使用_each的第二个context参数,是否实现对each没有影响。因此上面的实现一 不应该依赖_each的context,于是修改each如下:

Array.prototype.each = function(iterator,context){ 
var index = 0; 
this._each(function(value){ 
iterator.call(context,value,index++); 
}) 
}

这样一来,each方法的独立性提高了,在后续的Hash中也可以使用这个Enumerable了。任何看遍历的对象,只要提供了_each方法,就可以从Enumerable这里获得相应的方法。

因此,将上面的print例子用Enumerable的形式来实现,便得到如下的结果:

var Enumerable = {}; 
Enumerable.each = function(iterator, context) { 
var index = 0; 
this._each(function(value){ 
iterator.call(context, value, index++); 
}); 
return this; 
}; 
Enumerable.print = function(){ 
this.each(function(item){ 
console.log(item); 
}) 
}; 
Array.prototype._each = function(iterator,context){ 
for(var i = 0,len = this.length ; i < len ; i++){ 
iterator.call(context,this[i],i,this); 
} 
}; 
//下面的实现源码中是用的extend方法 
for(var key in Enumerable){ 
Array.prototype[key] = Enumerable[key]; 
}; 
[1,2,3,4].print();//1,2,3,4

理解each的实现是理解Enumerable对象的关键,后面的Array和Hash都混入Enumerable对象,颇为重要。
转载请注明来自小西山子【http://www.cnblogs.com/xesam/】
Javascript 相关文章推荐
Windows Live的@live.com域名注册漏洞 利用代码
Dec 27 Javascript
Jquery 插件学习实例1 插件制作说明与tableUI优化
Apr 02 Javascript
获取数组中最大最小值方法js代码(自写)
Aug 12 Javascript
jQuery基于ajax实现带动画效果无刷新柱状图投票代码
Aug 10 Javascript
ionic实现带字的toggle滑动组件
Aug 27 Javascript
原生js代码实现图片放大境效果
Oct 30 Javascript
详解react-router如何实现按需加载
Jun 15 Javascript
vue移动UI框架滑动加载数据的方法
Mar 12 Javascript
Makefile/cmake/node-gyp中区分判断不同平台的方法
Dec 18 Javascript
详解微信小程序胶囊按钮返回|首页自定义导航栏功能
Jun 14 Javascript
Electron vue的使用教程图文详解
Jul 05 Javascript
Ajax获取node服务器数据的完整步骤
Sep 20 Javascript
javascript椭圆旋转相册实现代码
Jan 16 #Javascript
Prototype源码浅析 Number部分
Jan 16 #Javascript
Prototype源码浅析 String部分(四)之补充
Jan 16 #Javascript
Prototype源码浅析 String部分(二)
Jan 16 #Javascript
深入理解JavaScript系列(11) 执行上下文(Execution Contexts)
Jan 15 #Javascript
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
Jan 15 #Javascript
深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!
Jan 15 #Javascript
You might like
php批量删除数据
2007/01/18 PHP
php cookie 作用范围?不要在当前页面使用你的cookie
2009/03/24 PHP
简单实现PHP留言板功能
2016/12/21 PHP
Jquery实现自定义窗口随意的拖拽
2014/03/12 Javascript
JavaScript中的Math.SQRT1_2属性使用简介
2015/06/14 Javascript
DEDECMS如何为文章添加HOT NEW标志图片
2015/08/14 Javascript
AngularJS 实现按需异步加载实例代码
2015/10/18 Javascript
探寻JavaScript中this指针指向
2016/04/23 Javascript
indexedDB bootstrap angularjs之 MVC DOMO (应用示例)
2016/06/20 Javascript
使用Node.js给图片加水印的方法
2016/11/15 Javascript
在nginx上部署vue项目(history模式)的方法
2017/12/28 Javascript
快速解决vue-cli不能初始化webpack模板的问题
2018/03/20 Javascript
JS中call和apply函数用法实例分析
2018/06/20 Javascript
快速解决vue动态绑定多个class的官方实例语法无效的问题
2018/09/05 Javascript
vue插槽slot的简单理解与用法实例分析
2020/03/14 Javascript
JS实现单张或多张图片持续无缝滚动的示例代码
2020/05/10 Javascript
详解如何修改 node_modules 里的文件
2020/05/22 Javascript
vue element el-transfer增加拖拽功能
2021/01/15 Vue.js
[55:18]Liquid vs Chaos 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
python scipy求解非线性方程的方法(fsolve/root)
2018/11/12 Python
用Python徒手撸一个股票回测框架搭建【推荐】
2019/08/05 Python
Django model 中设置联合约束和联合索引的方法
2019/08/06 Python
在python中实现求输出1-3+5-7+9-......101的和
2020/04/02 Python
python 基于卡方值分箱算法的实现示例
2020/07/17 Python
把Anaconda中的环境导入到Pycharm里面的方法步骤
2020/10/30 Python
CSS3中动画属性transform、transition和animation属性的区别
2016/09/25 HTML / CSS
CSS3实现跳动的动画效果
2016/09/12 HTML / CSS
介绍一下Python中webbrowser的用法
2013/05/07 面试题
市场部管理制度
2014/02/02 职场文书
模具专业毕业推荐信
2014/03/08 职场文书
储备店长岗位职责
2015/04/14 职场文书
单位计划生育责任书
2015/05/09 职场文书
因家庭原因离职的辞职信范文
2015/05/12 职场文书
公司职员入党自传书
2015/06/26 职场文书
MySQL库表名大小写的选择
2021/06/05 MySQL
MYSQL中文乱码问题的解决方案
2022/06/14 MySQL