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 相关文章推荐
js 创建快捷方式的代码(fso)
Nov 19 Javascript
JQuery实现简单验证码提示解决方案
Dec 20 Javascript
jquery创建一个新的节点对象(自定义结构/内容)的好方法
Jan 21 Javascript
js中的caller和callee属性介绍和例子
Jun 07 Javascript
node.js中的console.time方法使用说明
Dec 09 Javascript
JS中创建函数的三种方式及区别
Mar 13 Javascript
js修改onclick动作的四种方法(推荐)
Aug 18 Javascript
JS正则替换去空格的方法
Mar 24 Javascript
js实现图片轮播效果学习笔记
Jul 26 Javascript
Javascript 严格模式use strict详解
Sep 16 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
Aug 13 Javascript
代码解析React中setState同步和异步问题
Jun 03 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
php实现爬取和分析知乎用户数据
2016/01/26 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
Laravel 中创建 Zip 压缩文件并提供下载的实现方法
2019/04/02 PHP
jQuery AJAX回调函数this指向问题
2010/02/08 Javascript
利用js实现选项卡的特别效果的实例
2013/03/03 Javascript
Javascript拓展String方法小结
2013/07/08 Javascript
jQuery实现列表自动滚动循环滚动展示新闻
2014/08/22 Javascript
jquery实现炫酷的叠加层自动切换特效
2015/02/01 Javascript
jQuery如何获取动态添加的元素
2016/06/24 Javascript
Node.js + Redis Sorted Set实现任务队列
2016/09/19 Javascript
根据Bootstrap Paginator改写的js分页插件
2016/12/25 Javascript
微信小程序实现图片自适应(支持多图)
2017/01/25 Javascript
Js实现中国公民身份证号码有效性验证实例代码
2017/05/03 Javascript
JQuery实现定时刷新功能代码
2017/05/09 jQuery
vue使用keep-alive实现数据缓存不刷新
2017/10/21 Javascript
Javascript中从学习bind到实现bind的过程
2018/01/05 Javascript
JS实现的邮箱提示补全效果示例
2018/01/30 Javascript
JS实现的进制转换,浮点数相加,数字判断操作示例
2019/11/09 Javascript
vue 导出文件,携带请求头token操作
2020/09/10 Javascript
[54:56]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第三局
2016/03/06 DOTA
Python格式化压缩后的JS文件的方法
2015/03/05 Python
Python中for循环控制语句用法实例
2015/06/02 Python
python修改list中所有元素类型的三种方法
2018/04/09 Python
Python matplotlib 画图窗口显示到gui或者控制台的实例
2018/05/24 Python
pytorch训练imagenet分类的方法
2018/07/27 Python
一款基于css3的列表toggle特效实例教程
2015/01/04 HTML / CSS
信息与计算科学专业推荐信
2014/02/23 职场文书
授权委托书样本
2014/04/03 职场文书
《动手做做看》教学反思
2014/04/09 职场文书
党性心得体会
2014/09/03 职场文书
体育运动会广播稿
2014/10/05 职场文书
2015年教研组工作总结
2015/05/04 职场文书
小学秋季运动会加油口号及加油稿
2019/08/19 职场文书
nginx如何将http访问的网站改成https访问
2021/03/31 Servers
深入理解pytorch库的dockerfile
2022/06/10 Python
在python中读取和写入CSV文件详情
2022/06/28 Python