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 相关文章推荐
JavaScript 拖拉缩放效果
Dec 10 Javascript
javascript跟随滚动效果插件代码(javascript Follow Plugin)
Aug 03 Javascript
CSS+jQuery实现的一个放大缩小动画效果
Sep 24 Javascript
使用javascript控制cookie显示和隐藏背景图
Feb 12 Javascript
使用js实现数据格式化
Dec 03 Javascript
node.js+express制作网页计算器
Jan 17 Javascript
Html5 js实现手风琴效果
Apr 17 Javascript
JavaScript实现图片切换效果
Aug 12 Javascript
微信小程序自定义音乐进度条的实例代码
Aug 28 Javascript
Typescript3.9 常用新特性一览(推荐)
May 14 Javascript
JSONObject与JSONArray使用方法解析
Sep 28 Javascript
javascript实现简单留言板案例
Feb 09 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
中国站长站 For Dede4.0 采集规则
2007/05/27 PHP
PHP中json_encode、json_decode与serialize、unserialize的性能测试分析
2010/06/09 PHP
学习使用curl采集curl使用方法
2012/01/11 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十四)
2014/06/26 PHP
PHP数学运算函数大汇总(经典值得收藏)
2016/04/01 PHP
thinkPHP5实现数据库添加内容的方法
2017/10/25 PHP
Laravel模型间关系设置分表的方法示例
2018/04/21 PHP
php使用socket调用http和smtp协议实例小结
2019/07/26 PHP
Laravel Eloquent ORM 多条件查询的例子
2019/10/10 PHP
js setattribute批量设置css样式
2009/11/26 Javascript
纯javascript实现图片延时加载方法
2015/08/21 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
2016/01/27 Javascript
Angularjs在初始化未完毕时出现闪烁问题的解决方法分析
2016/08/05 Javascript
Javascript typeof与instanceof的区别
2016/10/18 Javascript
jQuery简单自定义图片轮播插件及用法示例
2016/11/21 Javascript
JS扩展类,克隆对象与混合类实例分析
2016/11/26 Javascript
详解Angular.js指令中scope类型的几种特殊情况
2017/02/21 Javascript
JS传参及动态修改页面布局
2017/04/13 Javascript
JavaScript闭包和回调详解
2017/08/09 Javascript
微信小程序学习笔记之获取位置信息操作图文详解
2019/03/29 Javascript
jQuery实现动态生成年月日级联下拉列表示例
2019/05/11 jQuery
JavaScript享元模式原理与用法实例详解
2020/03/09 Javascript
[01:46]新英雄登场
2019/09/10 DOTA
从零学python系列之新版本导入httplib模块报ImportError解决方案
2014/05/23 Python
在cmd命令行里进入和退出Python程序的方法
2018/05/12 Python
Python for循环中的陷阱详解
2018/07/13 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
使用 Python 处理 JSON 格式的数据
2019/07/22 Python
pandas中遍历dataframe的每一个元素的实现
2019/10/23 Python
python add_argument()用法解析
2020/01/29 Python
python 下划线的不同用法
2020/10/24 Python
css3加js做一个简单的3D行星运转效果实例代码
2017/01/18 HTML / CSS
Html5页面点击遮罩层背景关闭遮罩层
2020/11/30 HTML / CSS
村主任群众路线个人对照检查材料
2014/09/26 职场文书
学校食堂标语
2014/10/06 职场文书
高中生综合素质自我评价
2015/03/06 职场文书