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与函数式编程解释
Apr 27 Javascript
jQuery get和post 方法传值注意事项
Nov 03 Javascript
JS,Jquery获取select,dropdownlist,checkbox下拉列表框的值(示例代码)
Jan 11 Javascript
jQuery实现的仿select功能代码
Aug 19 Javascript
JS判断输入字符串长度实例代码(汉字算两个字符,字母数字算一个)
Aug 02 Javascript
jquery实现全选、不选、反选的两种方法
Sep 06 Javascript
JavaScript中的ajax功能的概念和示例详解
Oct 17 Javascript
jQuery中DOM节点删除之empty与remove
Jan 20 Javascript
很棒的vue弹窗组件
May 24 Javascript
理解 javascript 中的函数表达式与函数声明
Jul 07 Javascript
vue实现手机号码抽奖上下滚动动画示例
Oct 18 Javascript
JavaScript实现一个带AI的井字棋游戏源码
May 21 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
Netflix将与CLAMP、乙一以及冲方丁等6名知名制作人合伙展开原创动画计划!
2020/03/06 日漫
《被神捡到的男人》动画化计划进行中!
2020/03/06 日漫
example2.php
2006/10/09 PHP
关于BIG5-HKSCS的解决方法
2007/03/20 PHP
PHP无法访问远程mysql的问题分析及解决
2013/05/16 PHP
PHP中判断变量为空的几种方法分享
2013/08/26 PHP
把JS与CSS写在同一个文件里的书写方法
2007/06/02 Javascript
javascript实现的动态添加表单元素input,button等(appendChild)
2007/11/24 Javascript
javascript arguments 传递给函数的隐含参数
2009/08/21 Javascript
myEvent.js javascript跨浏览器事件框架
2011/10/24 Javascript
javascript:文字不间断向左移动的实例代码
2013/08/08 Javascript
DOM节点删除函数removeChild()用法实例
2015/01/12 Javascript
jQuery内容过滤选择器用法分析
2015/02/10 Javascript
JS+CSS实现带关闭按钮DIV弹出窗口的方法
2015/02/27 Javascript
JQuery查找DOM节点的方法
2015/06/11 Javascript
AngularJS国际化详解及示例代码
2016/08/18 Javascript
在HTML文档中嵌入JavaScript的四种方法
2018/05/07 Javascript
jQuery中getJSON跨域原理的深入讲解
2020/09/02 jQuery
[04:27]DOTA2官方论坛水友赛集锦
2013/09/16 DOTA
基于python实现的抓取腾讯视频所有电影的爬虫
2016/04/22 Python
python中执行shell的两种方法总结
2017/01/10 Python
python单例设计模式实现解析
2020/01/07 Python
Python request使用方法及问题总结
2020/04/26 Python
keras的backend 设置 tensorflow,theano操作
2020/06/30 Python
通俗讲解python 装饰器
2020/09/07 Python
巴西最大的体育用品商城:Netshoes巴西
2016/11/29 全球购物
如何在Shell脚本中使用函数
2015/09/06 面试题
电子商务专业学生的自我鉴定
2013/11/28 职场文书
公司门卫管理制度
2014/02/01 职场文书
销售个人求职信范文
2014/04/28 职场文书
解除劳动关系协议书范文
2014/09/11 职场文书
党员个人整改措施
2014/10/24 职场文书
法定代表人资格证明书
2015/06/18 职场文书
幼儿园六一主持词
2015/06/30 职场文书
聊聊pytorch测试的时候为何要加上model.eval()
2021/05/23 Python
如何使用python包中的sched事件调度器
2022/04/30 Python