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 相关文章推荐
JSQL 基于客户端的成绩统计实现方法
May 05 Javascript
防止页面被iframe(兼容IE,Firefox火狐)
Jul 04 Javascript
jQuery获取css z-index在各种浏览器中的返回值
Sep 15 Javascript
JavaScript获取和设置CheckBox状态的简单方法
Jul 05 Javascript
jQuery获得IE版本不准确webbrowser的解决方法
Feb 23 Javascript
使用原生js实现页面蒙灰(mask)效果示例代码
Jun 20 Javascript
兼容IE、firefox以及chrome的js获取时间(getFullYear)
Jul 04 Javascript
JS实现关键字搜索时的相关下拉字段效果
Aug 05 Javascript
javascript实现tab切换的四种方法
Nov 05 Javascript
javascript深拷贝和浅拷贝详解
Feb 14 Javascript
JavaScript中concat复制数组方法浅析
Jan 20 Javascript
Vue3中toRef与toRefs的区别
Mar 24 Vue.js
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+AJAX聊天程序[聊天室]提供下载
2007/07/21 PHP
php代码运行时间查看类代码分享
2011/08/06 PHP
PHP+MySQL投票系统的设计和实现分享
2012/09/23 PHP
php中autoload的用法总结
2013/11/08 PHP
php分页函数完整实例代码
2014/09/22 PHP
基于laravel制作APP接口(API)
2016/03/15 PHP
PHP面向对象多态性实现方法简单示例
2017/09/27 PHP
php post json参数的传递和接收处理方法
2018/05/31 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
Laravel 实现在Blade模版中使用全局变量代替路径的例子
2019/10/22 PHP
jQuery使用动态渲染表单功能完成ajax文件下载
2013/01/15 Javascript
为jQuery添加Webkit的触摸的方法分享
2014/02/02 Javascript
JS实现文档加载完成后执行代码
2015/07/09 Javascript
基于JavaScript实现表单密码的隐藏和显示出来
2016/03/02 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
2017/03/14 Javascript
javascript 取小数点后几位几种方法总结
2017/08/02 Javascript
详解Vue单元测试case写法
2018/05/24 Javascript
基于Vue实现关键词实时搜索高亮显示关键词
2018/07/21 Javascript
ES6中字符串的使用方法扩展
2019/06/04 Javascript
React Hooks 实现和由来以及解决的问题详解
2020/01/17 Javascript
小程序实现列表展开收起效果
2020/07/29 Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
2020/07/31 Javascript
在vue中获取wangeditor的html和text的操作
2020/10/23 Javascript
浅谈numpy数组中冒号和负号的含义
2018/04/18 Python
查找python项目依赖并生成requirements.txt的方法
2018/07/10 Python
python 正则表达式贪婪模式与非贪婪模式原理、用法实例分析
2019/10/14 Python
Python如何使用argparse模块处理命令行参数
2019/12/11 Python
tensorboard实现同时显示训练曲线和测试曲线
2020/01/21 Python
详解pyinstaller生成exe的闪退问题解决方案
2020/06/19 Python
意大利时尚精品店:Nugnes 1920
2020/02/10 全球购物
硕士研究生自我鉴定范文
2013/12/27 职场文书
安全生产管理合理化建议书
2014/03/12 职场文书
酒店优秀员工推荐信
2015/03/24 职场文书
跑吧孩子观后感
2015/06/10 职场文书
2016年度基层党建工作公开承诺书
2016/03/25 职场文书
python基础之类属性和实例属性
2021/10/24 Python