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 相关文章推荐
分享一道笔试题[有n个直线最多可以把一个平面分成多少个部分]
Oct 12 Javascript
Js动态添加复选框Checkbox的实例方法
Apr 08 Javascript
jQuery多级弹出菜单插件ZoneMenu
Dec 18 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
Jan 28 Javascript
JavaScript点击按钮后弹出透明浮动层的方法
May 11 Javascript
javascript删除元素节点removeChild()用法实例
May 26 Javascript
JavaScript+Java实现HTML页面转为PDF文件保存的方法
May 30 Javascript
Router解决跨模块下的页面跳转示例
Jan 11 Javascript
layui radio性别单选框赋值方法
Aug 15 Javascript
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
Jun 07 Javascript
基于Proxy的小程序状态管理实现
Jun 14 Javascript
JavaScript实现显示和隐藏图片
Apr 29 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调用Twitter的RSS的实现代码
2010/03/10 PHP
利用中国天气预报接口实现简单天气预报
2014/01/20 PHP
Yii基于数组和对象的Model查询技巧实例详解
2015/12/28 PHP
删除重复数据的算法
2006/11/23 Javascript
十分钟打造AutoComplete自动完成效果代码
2009/12/26 Javascript
jQuery点击弹出下拉菜单的小例子
2013/08/01 Javascript
javascript不同类型数据之间的运算的转换方法
2014/02/13 Javascript
Node.js编码规范
2014/07/14 Javascript
jQuery/CSS3图片特效插件整理推荐
2014/12/07 Javascript
跨域资源共享 CORS 详解
2016/04/26 Javascript
jQuery实现ToolTip元素定位显示功能示例
2016/11/23 Javascript
10道典型的JavaScript面试题
2017/03/22 Javascript
详解在React中跨组件分发状态的三种方法
2018/08/09 Javascript
vue项目添加多页面配置的步骤详解
2019/05/22 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
2019/09/12 Javascript
WebStorm无法正确识别Vue3组合式API的解决方案
2021/02/18 Vue.js
[01:00:25]2018DOTA2亚洲邀请赛3月30日 小组赛A组 VG VS Liquid
2018/03/31 DOTA
python中pass语句用法实例分析
2015/04/30 Python
使用pandas对矢量化数据进行替换处理的方法
2018/04/11 Python
用Django写天气预报查询网站
2018/10/21 Python
Python中按键来获取指定的值
2019/03/02 Python
Python实现的企业粉丝抽奖功能示例
2019/07/26 Python
tensorboard显示空白的解决
2020/02/15 Python
Python sorted对list和dict排序
2020/06/09 Python
删除pycharm鼠标右键快捷键打开项目的操作
2021/01/16 Python
python中的unittest框架实例详解
2021/02/05 Python
澳大利亚最好的在线时尚精品店:Princess Polly
2018/01/03 全球购物
护士毕业生自我鉴定
2014/02/08 职场文书
《自选商场》教学反思
2014/02/14 职场文书
2014年社区党建工作汇报材料
2014/11/02 职场文书
给女朋友道歉的话大全
2015/01/20 职场文书
2016大学军训心得体会
2016/01/11 职场文书
掌握这项技巧,一年阅读300本书不是梦
2019/09/12 职场文书
Ajax是什么?Ajax高级用法之Axios技术
2021/04/21 Javascript
opencv 分类白天与夜景视频的方法
2021/06/05 Python
CentOS下安装Jenkins的完整步骤
2022/04/07 Servers