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获取QueryString的方法小结
Feb 28 Javascript
JS实现图片横向滚动效果示例代码
Sep 04 Javascript
AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】
Nov 02 Javascript
js实现炫酷的左右轮播图
Jan 18 Javascript
jQuery弹出层插件popShow用法示例
Jan 23 Javascript
Node.js dgram模块实现UDP通信示例代码
Sep 26 Javascript
jQuery实现的页面遮罩层功能示例【测试可用】
Oct 14 jQuery
JS/jQuery实现超简单的Table表格添加,删除行功能示例
Jul 31 jQuery
JavaScript 俄罗斯方块游戏实现方法与代码解释
Apr 08 Javascript
深度解读vue-resize的具体用法
Jul 08 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
Nov 06 Javascript
js判断两个数组相等的5种方法
May 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 xml 入门学习资料
2011/01/01 PHP
php版微信发红包接口用法示例
2016/09/23 PHP
Swoole 5将移除自动添加Event::wait()特性详解
2019/07/10 PHP
Smarty缓存机制实例详解【三种缓存方式】
2019/07/20 PHP
nullJavascript中创建对象的五种方法实例
2013/05/07 Javascript
解析javascript 浏览器关闭事件
2013/07/08 Javascript
自定义ExtJS控件之下拉树和下拉表格附源码
2013/10/15 Javascript
简洁Ajax函数处理(示例代码)
2013/11/15 Javascript
jQuery的ready方法详解
2014/11/27 Javascript
jQuery实现鼠标划过修改样式的方法
2015/04/14 Javascript
JS实现日期时间动态显示的方法
2015/12/07 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
canvas实现粒子时钟效果
2017/02/06 Javascript
深入浅析JSONAPI在PHP中的应用
2017/12/24 Javascript
在vue项目中引用Iview的方法
2018/09/14 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
vue elementUI 表单校验功能之数组多层嵌套
2019/06/04 Javascript
Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)
2020/08/28 Javascript
vue v-model的用法解析
2020/10/19 Javascript
Python使用xlwt模块操作Excel的方法详解
2018/03/27 Python
python 实现数字字符串左侧补零的方法
2018/12/04 Python
Python使用Shelve保存对象方法总结
2019/01/28 Python
Python3安装pip工具的详细步骤
2019/10/14 Python
python单例模式原理与创建方法实例分析
2019/10/26 Python
将自己的数据集制作成TFRecord格式教程
2020/02/17 Python
Python requests设置代理的方法步骤
2020/02/23 Python
PyTorch中torch.tensor与torch.Tensor的区别详解
2020/05/18 Python
Python类成员继承重写的实现
2020/09/16 Python
HTML5 Geolocation API的正确使用方法
2018/12/04 HTML / CSS
SmartBuyGlasses美国官网:太阳眼镜和眼镜
2017/08/20 全球购物
意大利消费电子产品购物网站:SLG Store
2019/12/26 全球购物
高三自我鉴定怎么写
2013/10/19 职场文书
放飞理想演讲稿
2014/09/09 职场文书
2016年端午节寄语
2015/12/04 职场文书
2019新学期家长会工作计划
2019/08/21 职场文书
Java面试题冲刺第十九天--数据库(4)
2021/08/07 Java/Android