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 拖拉缩放效果
Dec 10 Javascript
js+xml生成级联下拉框代码
Jul 24 Javascript
ECMAScript6的新特性箭头函数(Arrow Function)详细介绍
Jun 07 Javascript
JS实现模拟风力的雪花飘落效果
May 13 Javascript
jquery层级选择器的实现(匹配后代元素div)
Sep 05 Javascript
AngularJS监听路由的变化示例代码
Sep 23 Javascript
在js里怎么实现Xcode里的callFuncN方法(详解)
Nov 05 Javascript
利用jquery获取select下拉框的值
Nov 23 Javascript
Bootstrap4如何定制自己的颜色和风格
Feb 26 Javascript
微信小程序代码上传、审核发布小程序
May 18 Javascript
layui 根据后台数据动态创建下拉框并同时默认选中的实例
Sep 02 Javascript
原生javascript如何实现共享onload事件
Jul 03 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+mysql事务rollback&amp;commit示例
2010/02/08 PHP
gd库图片下载类实现下载网页所有图片的php代码
2012/08/20 PHP
PHP PDOStatement::columnCount讲解
2019/01/30 PHP
js 禁用只读文本框获得焦点时的退格键
2010/04/25 Javascript
JavaScript高级程序设计阅读笔记(六) ECMAScript中的运算符(二)
2012/02/27 Javascript
jquery.validate使用时遇到的问题
2015/05/25 Javascript
jQuery插件简单实现方法
2015/07/18 Javascript
js轮盘抽奖实例分析
2020/04/17 Javascript
JS实现的系统调色板完整实例
2016/12/21 Javascript
微信小程序之拖拽排序(代码分享)
2017/01/21 Javascript
JS实现获取进今年第几天是周几的方法分析
2018/06/27 Javascript
详解如何为你的angular app构建一个第三方库
2018/12/07 Javascript
关于layui flow loading占位图的实现方法
2019/09/21 Javascript
Vuex modules模式下mapState/mapMutations的操作实例
2019/10/17 Javascript
Angular进行简单单元测试的实现方法实例
2020/08/16 Javascript
vue插件--仿微信小程序showModel实现模态提示窗功能
2020/08/19 Javascript
js实现飞机大战小游戏
2020/08/26 Javascript
写一个Vue loading 插件
2020/11/09 Javascript
[05:28]刀塔密之一:团结则存
2014/07/03 DOTA
深入理解Python中各种方法的运作原理
2015/06/15 Python
浅析Python中signal包的使用
2015/11/13 Python
Pycharm 操作Django Model的简单运用方法
2018/05/23 Python
详解Pytorch 使用Pytorch拟合多项式(多项式回归)
2018/05/24 Python
Python通过cv2读取多个USB摄像头
2019/08/28 Python
方太官方网上商城:销售方太抽油烟机、燃气灶、消毒柜等
2017/01/17 全球购物
台湾时尚彩瞳专门店:imeime
2019/08/16 全球购物
火山咖啡:Volcanica Coffee
2019/10/29 全球购物
银行会计职员个人的自我评价
2013/09/29 职场文书
旅行社优秀创业计划书
2014/08/16 职场文书
2014年企业工会工作总结
2014/11/12 职场文书
2014年妇产科工作总结
2014/12/08 职场文书
幼师中班个人总结
2015/02/12 职场文书
军训阅兵新闻稿
2015/07/17 职场文书
关于社会实践的心得体会(2016最新版)
2016/01/25 职场文书
如何获取numpy array前N个最大值
2021/05/14 Python
DE1107机评
2022/04/05 无线电