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类型增加方法的实现代码(增加功能)
Dec 29 Javascript
JavaScript网页定位详解
Jan 13 Javascript
简单的ajax连接库分享(不用jquery的ajax)
Jan 19 Javascript
可自定义速度的js图片无缝滚动示例分享
Jan 20 Javascript
jquery、js调用iframe父窗口与子窗口元素的方法整理
Jul 31 Javascript
jQuery焦点控制图层展示延迟隐藏的方法
Mar 09 Javascript
javascript简易画板开发
Apr 12 Javascript
prototype与__proto__区别详细介绍
Jan 09 Javascript
通过vue提供的keep-alive减少对服务器的请求次数
Apr 01 Javascript
vue.js循环radio的实例
Nov 07 Javascript
Vue表单控件数据绑定方法详解
Feb 05 Javascript
如何通过简单的代码描述Angular父组件、子组件传值
Apr 07 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
phpMyAdmin 安装教程全攻略
2007/03/19 PHP
php学习 字符串课件
2008/06/15 PHP
set_exception_handler函数在ThinkPHP中的用法
2014/10/31 PHP
PHP从FLV文件获取视频预览图的方法
2015/03/12 PHP
PHP实现的构造sql语句类实例
2016/02/03 PHP
分享别人写的一个小型js框架
2007/08/13 Javascript
jQuery1.6 类型判断实现代码
2011/09/01 Javascript
node.js中的fs.fstat方法使用说明
2014/12/15 Javascript
简单谈谈jQuery(function(){})与(function(){})(jQuery)
2014/12/19 Javascript
jQuery实现移动端滑块拖动选择数字效果
2015/12/24 Javascript
Bootstrap布局之栅格系统详解
2016/06/13 Javascript
jquery之别踩白块游戏的简单实现
2016/07/25 Javascript
js获取form表单所有数据的简单方法
2016/08/18 Javascript
JavaScript高仿支付宝倒计时页面及代码实现
2016/10/21 Javascript
vue双向绑定的简单实现
2016/12/22 Javascript
浅谈vue项目优化之页面的按需加载(vue+webpack)
2017/12/11 Javascript
基于vue2.x的电商图片放大镜插件的使用
2018/01/22 Javascript
JS运动特效之同时运动实现方法分析
2018/01/24 Javascript
解决eclipse中没有js代码提示的问题
2018/10/10 Javascript
Javascript实现秒表倒计时功能
2018/11/17 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
2018/12/05 Javascript
彻底揭秘keep-alive原理(小结)
2019/05/05 Javascript
react 移动端实现列表左滑删除的示例代码
2019/07/04 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
2019/09/25 Javascript
CountUp.js数字滚动插件使用方法详解
2019/10/17 Javascript
Vue父子传递实例讲解
2020/02/14 Javascript
[02:31]2014DOTA2国际邀请赛2009专访:干爹表现出乎意料 看好DK杀回决赛
2014/07/20 DOTA
python开启多个子进程并行运行的方法
2015/04/18 Python
对python中array.sum(axis=?)的用法介绍
2018/06/28 Python
使用Python 正则匹配两个特定字符之间的字符方法
2018/12/24 Python
html5中为audio标签增加停止按钮动作实现方法
2013/01/04 HTML / CSS
详解使用双缓存解决Canvas clearRect引起的闪屏问题
2019/04/29 HTML / CSS
EntityManager都有哪些方法
2013/11/01 面试题
开门红主持词
2014/04/02 职场文书
副职竞争上岗演讲稿
2014/05/12 职场文书
2015年酒店前台工作总结
2015/04/20 职场文书