Prototype ObjectRange对象学习


Posted in Javascript onJuly 19, 2009

Ranges represent an interval of values. The value type just needs to be “compatible,” that is, to implement a succ method letting us step from one value to the next (its successor).

Prototype provides such a method for Number and String, but you are of course welcome to implement useful semantics in your own objects, in order to enable ranges based on them.

ObjectRange对象基本就是实现了连续的数字或者字符串,其中只包含一个方法,include,判断某个数字或者字符串是否在ObjectRange里。并且ObjectRange对象还混入了Enumerable的方法,所以可以直接在ObjectRange对象上调用Enumerable对象里面的方法。

//创建ObjectRange的便捷方法 
function $R(start, end, exclusive) { 
return new ObjectRange(start, end, exclusive); 
} //创建ObjectRange对象并且继承自Enumerable 
var ObjectRange = Class.create(Enumerable, (function() { 
    //初始化方法,exclusive为true时,不包含end数值,默认为undefined也就相当于false 
function initialize(start, end, exclusive) { 
this.start = start; 
this.end = end; 
this.exclusive = exclusive; 
} 
//覆盖Enumerable里面的_each方法,在遍历ObjectRange对象时需要用到此方法 
function _each(iterator) { 
var value = this.start; 
while (this.include(value)) { 
iterator(value); 
value = value.succ(); 
} 
} 
//判断某个数值或者字符串是否包含在ObjectRange对象里 
function include(value) { 
if (value < this.start) 
return false; 
if (this.exclusive) 
return value < this.end; 
return value <= this.end; 
} 
return { 
initialize: initialize, 
_each: _each, 
include: include 
}; 
})());

看一下示例,然后在详细解释一些细节:
$A($R('a', 'e')) 
// -> ['a', 'b', 'c', 'd', 'e'], no surprise there //千万不要尝试输出下面返回的结果,否者将会造成浏览器直接死掉 
$A($R('ax', 'ba')) 
// -> Ouch! Humongous array, starting as ['ax', 'ay', 'az', 'a{', 'a|', 'a}', 'a~'...]

这里说一下$A($R('a', 'e')),如何返回值。首先看$A方法,前面的文章【Prototype 学习——工具函数学习($A方法)】中已经详细讲解了$A方法,不知道请自行参考。在$A方法里面有这样一句:if ('toArray' in Object(iterable)) return iterable.toArray();我们知道,ObjectRange里面混入了Enumerable里面的方法,也就是说间接实现了toArray方法,那么看一下Enumerable里面的toArray方法:
function toArray() { 
return this.map(); 
} //======> this.map() 
//我们注意到在返回的时候map方法被映射到了collect方法 
return { 
//... 
collect: collect, 
map: collect, 
//... 
} 
//======> collect() 
//在本例中这个方法其实就相当于返回一个数组,因为传进来的参数都是undefined。这里面有一个this.each方法,继续查看 
function collect(iterator, context) { 
iterator = iterator || Prototype.K; 
var results = []; 
this.each(function(value, index) { 
results.push(iterator.call(context, value, index)); 
}); 
return results; 
} 
//======> this.each() 
//终于看到this._each了,现在明白为什么ObjectRange里面会重写了_each方法了吧。在遍历的时候要用到这个方法 
function each(iterator, context) { 
var index = 0; 
try { 
this._each(function(value) { 
iterator.call(context, value, index++); 
}); 
} catch (e) { 
if (e != $break) throw e; 
} 
return this; 
} 
//======> this._each() 
//详细说明一下this._each() 
//关键就是succ()这个方法,因为_each里面使用这个方法产生下一个数值。 
//这个succ()在哪里呢?在Number.prototype和String.prototype里面定义了这个方法 
function _each(iterator) { 
var value = this.start; 
while (this.include(value)) { 
iterator(value); 
value = value.succ(); 
} 
} 
//下面两个方法我就不讲了吧。 
//======> String.prototype.succ() 
function succ() { 
return this.slice(0, this.length - 1) + 
String.fromCharCode(this.charCodeAt(this.length - 1) + 1); 
} 
//======> Number.prototype.succ() 
function succ() { 
return this + 1; 
} 
//综上所述,如果你自己想定义其它类型的ObjectRange对象,譬如Date类型,那么你就要自己实现succ()方法,用来生成连续的对象

上面的流程将清楚了,但一些函数没有仔细讲,等讲到这些对象的时候在仔细说明里面的函数。下面看几个include的示例吧:
$R(1, 10).include(5) 
// -> true 
$R('a', 'h').include('x') 
// -> false 
$R(1, 10).include(10) 
// -> true 
$R(1, 10, true).include(10) 
// -> false
Javascript 相关文章推荐
Javascript valueOf 使用方法
Dec 28 Javascript
通过jquery的$.getJSON做一个跨域ajax请求试验
May 03 Javascript
推荐40款强大的 jQuery 导航插件和教程(上篇)
Sep 14 Javascript
jquery 倒计时效果实现秒杀思路
Sep 11 Javascript
键盘上一张下一张兼容IE/google/firefox等浏览器
Jan 28 Javascript
js计算德州扑克牌面值的方法
Mar 04 Javascript
详解JavaScript中的Unescape()和String() 函数
Nov 09 Javascript
Bootstrap学习笔记之进度条、媒体对象实例详解
Mar 09 Javascript
vue实现点击选中,其他的不选中方法
Sep 05 Javascript
js常见遍历操作小结
Jun 06 Javascript
vue源码nextTick使用及原理解析
Aug 13 Javascript
node.JS路径解析之PATH模块使用方法详解
Feb 06 Javascript
Prototype RegExp对象 学习
Jul 19 #Javascript
Prototype Class对象学习
Jul 19 #Javascript
javascript iframe内的函数调用实现方法
Jul 19 #Javascript
9个javascript语法高亮插件 推荐
Jul 18 #Javascript
Google Map Api和GOOGLE Search Api整合实现代码
Jul 18 #Javascript
比较简单的异步加载JS文件的代码
Jul 18 #Javascript
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
Jul 18 #Javascript
You might like
二次元帅气男生排行榜,只想悄悄收藏系列
2020/03/04 日漫
建立文件交换功能的脚本(三)
2006/10/09 PHP
php各种编码集详解和以及在什么情况下进行使用
2011/09/11 PHP
php实现ip白名单黑名单功能
2015/03/12 PHP
php截取视频指定帧为图片
2016/05/16 PHP
Laravel5.* 打印出执行的sql语句的方法
2017/07/24 PHP
js利用div背景,做一个竖线的效果。
2008/11/22 Javascript
jQuery学习笔记[1] jQuery中的DOM操作
2010/12/03 Javascript
javascript 使用 NodeList需要注意的问题
2013/03/04 Javascript
Javascript中各种trim的实现详细解析
2013/12/10 Javascript
JavaScript返回当前会话cookie全部键值对照的方法
2015/04/03 Javascript
JS替换字符串中空格方法
2015/04/17 Javascript
bootstrap daterangepicker汉化以及扩展功能
2017/06/15 Javascript
jQuery实现碰到边缘反弹的动画效果
2018/02/24 jQuery
JQuery常见节点操作实例分析
2019/05/15 jQuery
[37:47]IG vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python中扩展包的安装方法详解
2017/06/14 Python
python实现指定字符串补全空格、前面填充0的方法
2018/11/16 Python
python程序封装为win32服务的方法
2021/03/07 Python
WxPython建立批量录入框窗口
2019/02/27 Python
pyqt5使用按钮进行界面的跳转方法
2019/06/19 Python
Pandas时间序列基础详解(转换,索引,切片)
2020/02/26 Python
python中wx模块的具体使用方法
2020/05/15 Python
keras的三种模型实现与区别说明
2020/07/03 Python
Python中pass的作用与使用教程
2020/11/13 Python
美国眼镜在线零售商:Dualens
2019/12/07 全球购物
Chinti & Parker官网:奢华羊绒女装和创新针织设计
2021/01/01 全球购物
WEB控件及HTML服务端控件能否调用客户端方法?如果能,请解释如何调用?
2015/08/25 面试题
高级护理实习生自荐信
2013/09/28 职场文书
应届生煤化工求职信
2013/10/21 职场文书
市场营销毕业生自荐信范文
2014/04/01 职场文书
涉外离婚协议书怎么写
2014/11/20 职场文书
关于成立领导小组的通知
2015/04/23 职场文书
新学期感想
2015/08/10 职场文书
Nginx服务器如何设置url链接
2021/03/31 Servers
Redis 哨兵集群的实现
2021/06/18 Redis