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 八进制转义字符(8进制)
Apr 08 Javascript
三种取消选中单选框radio的方法
Sep 09 Javascript
jQuery搜索同辈元素方法
Feb 10 Javascript
JavaScript判断对象是否为数组
Dec 22 Javascript
JS拖拽组件学习使用
Jan 19 Javascript
jQuery实现的导航下拉菜单效果示例
Sep 05 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
Mar 08 Javascript
微信小程序 页面传值详解
Mar 10 Javascript
Vue中保存用户登录状态实例代码
Jun 07 Javascript
Vue中父组件向子组件通信的方法
Jul 11 Javascript
一步一步的了解webpack4的splitChunk插件(小结)
Sep 17 Javascript
node.js中ws模块创建服务端和客户端,网页WebSocket客户端
Mar 06 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 日期加减的类,很不错
2009/10/10 PHP
PHP学习之正则表达式
2011/04/17 PHP
PHP文件操作实现代码分享
2011/09/01 PHP
PHP MYSQL简易交互式站点开发
2016/12/27 PHP
PHP使用正则表达式实现过滤非法字符串功能示例
2018/06/04 PHP
PHP array_shift()用法实例分析
2019/01/07 PHP
php屏蔽错误及提示的方法
2020/05/10 PHP
javascript中普通函数的使用介绍
2013/12/19 Javascript
多引号嵌套的变量命名的问题
2014/05/09 Javascript
JS匿名函数类生成方式实例分析
2016/11/26 Javascript
微信小程序 HTTPS报错整理常见问题及解决方案
2016/12/14 Javascript
解决html input验证只能输入数字,不能输入其他的问题
2017/07/21 Javascript
基于vue配置axios的方法步骤
2017/11/09 Javascript
koa+mongoose实现简单增删改查接口的示例代码
2019/05/13 Javascript
node中实现删除目录的几种方法
2019/06/24 Javascript
javascript前端实现多视频上传
2020/12/13 Javascript
跟老齐学Python之用while来循环
2014/10/02 Python
用Python实现一个简单的能够发送带附件的邮件程序的教程
2015/04/08 Python
利用Python爬虫给孩子起个好名字
2017/02/14 Python
基于Python实现的微信好友数据分析
2018/02/26 Python
如何通过python画loss曲线的方法
2019/06/26 Python
Python 共享变量加锁、释放详解
2019/08/28 Python
python如何删除文件、目录
2020/06/23 Python
Oracle的内存结构(Memory structures)
2015/06/10 面试题
店长岗位的工作内容
2013/11/12 职场文书
高中班长自我鉴定
2013/12/20 职场文书
孝老爱亲模范事迹
2014/01/24 职场文书
工厂会计员职责
2014/02/06 职场文书
投标保密承诺书
2014/05/19 职场文书
学校领导班子四风问题整改意见
2014/10/02 职场文书
大学生考试作弊被抓检讨书
2014/12/27 职场文书
如何做好员工培训计划?
2019/07/09 职场文书
导游词之包公祠
2019/11/25 职场文书
温馨祝福晨语:美丽的一天从我的问候开始
2019/11/28 职场文书
关于golang高并发的实现与注意事项说明
2021/05/08 Golang
Pytorch GPU内存占用很高,但是利用率很低如何解决
2021/06/01 Python