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 相关文章推荐
js判断浏览器的比较全的代码
Feb 13 Javascript
日历查询的算法 如何计算某一天是星期几
Dec 12 Javascript
jquery拖动插件(jquery.drag)使用介绍
Jun 18 Javascript
网站内容禁止复制和粘贴、另存为的js代码
Feb 26 Javascript
jQuery的图片滑块焦点图插件整理推荐
Dec 07 Javascript
jquery实现仿Flash的横向滑动菜单效果代码
Sep 17 Javascript
JQueryEasyUI框架下的combobox的取值和绑定的方法
Jan 22 Javascript
微信小程序 常用工具类详解及实例
Feb 15 Javascript
vue的一个分页组件的示例代码
Dec 25 Javascript
微信小程序获取用户信息的两种方法wx.getUserInfo与open-data实例分析
May 03 Javascript
小程序的上传文件接口的注意要点解析
Sep 17 Javascript
使用Promise封装小程序wx.request的实现方法
Nov 13 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文本操作类
2006/11/25 PHP
php处理json时中文问题的解决方法
2011/04/12 PHP
php验证码的制作思路和实现方法
2015/11/12 PHP
PHP快速生成各种信息提示框的方法
2016/02/03 PHP
利用PHP实现开心消消乐的算法示例
2017/10/12 PHP
PHP封装的page分页类定义与用法完整示例
2018/12/24 PHP
实例讲解PHP验证邮箱是否合格
2019/01/28 PHP
JavaScript 原型继承
2011/12/26 Javascript
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
AngularJS入门知识之MVW类框架的编程思想探讨
2014/12/08 Javascript
谈一谈javascript闭包
2016/01/28 Javascript
AngularJS实现textarea记录只能输入规定数量的字符并显示
2016/04/26 Javascript
AngularJS ng-repeat指令中使用track by子语句解决重复数据遍历错误问题
2017/01/21 Javascript
Bootstrap 网格系统布局详解
2017/03/19 Javascript
es6学习笔记之Async函数的使用示例
2017/05/11 Javascript
通过实例解析js简易模块加载器
2019/06/17 Javascript
node爬取新型冠状病毒的疫情实时动态
2020/02/06 Javascript
深入解析微信小程序开发中遇到的几个小问题
2020/07/11 Javascript
JavaScript浅层克隆与深度克隆示例详解
2020/09/01 Javascript
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
Python提取网页中超链接的方法
2016/09/18 Python
Python用UUID库生成唯一ID的方法示例
2016/12/15 Python
python os用法总结
2018/06/08 Python
用Python实现最速下降法求极值的方法
2019/07/10 Python
python 如何利用argparse解析命令行参数
2020/09/11 Python
python不同版本的_new_不同点总结
2020/12/09 Python
网络艺术零售业的先驱者:artrepublic
2017/09/26 全球购物
日本动漫周边服饰销售网站:Atsuko
2019/12/16 全球购物
skyn ICELAND官网:冰岛成分天然护肤品
2020/08/24 全球购物
优秀毕业生找工作自荐信
2014/06/23 职场文书
高效课堂标语
2014/06/26 职场文书
2014年工程工作总结
2014/11/25 职场文书
先进党支部申报材料
2014/12/24 职场文书
会议通知
2015/04/15 职场文书
2015年机关后勤工作总结
2015/05/26 职场文书
win sever 2022如何占用操作主机角色
2022/06/25 Servers