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 相关文章推荐
表单的一些基本用法与技巧
Jul 15 Javascript
range 标准化之获取
Aug 28 Javascript
清除div下面的所有标签的方法
Feb 17 Javascript
JavaScript中一个奇葩的IE浏览器判断方法
Apr 16 Javascript
javascript函数声明和函数表达式区别分析
Dec 02 Javascript
jQuery添加options点击事件并传值实例代码
May 18 Javascript
如何使用bootstrap框架 bootstrap入门必看!
Apr 13 Javascript
基于AngularJS实现的工资计算器实例
Jun 16 Javascript
VueJs组件之父子通讯的方式
May 06 Javascript
微信小程序实现两边小中间大的轮播效果的示例代码
Dec 07 Javascript
jquery多级树形下拉菜单的实例代码
Jul 09 jQuery
Vue3.0写自定义指令的简单步骤记录
Jun 27 Vue.js
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 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)
2012/06/07 PHP
ubuntu下编译安装xcache for php5.3 的具体操作步骤
2013/06/18 PHP
Linux下PHP加速器APC的安装与配置笔记
2014/10/24 PHP
PHP文件下载实例代码浅析
2016/08/17 PHP
详解Yaf框架PHPUnit集成测试方法
2017/12/27 PHP
Yii Framework框架使用PHPExcel组件的方法示例
2019/07/24 PHP
php设计模式之策略模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
JQuery从头学起第一讲
2010/07/04 Javascript
关于this和self的使用说明
2010/08/01 Javascript
jquery实现居中弹出层代码
2010/08/25 Javascript
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
2012/03/01 Javascript
jQuery插件slick实现响应式移动端幻灯片图片切换特效
2015/04/12 Javascript
jQuery+css实现非常漂亮的水平导航菜单效果
2016/07/27 Javascript
在网页中插入百度地图的步骤详解
2016/12/02 Javascript
angularjs实现首页轮播图效果
2017/04/14 Javascript
原生JS实现瀑布流插件
2018/02/06 Javascript
Vue+ElementUI实现表单动态渲染、可视化配置的方法
2018/03/07 Javascript
浅谈layui框架自带分页和表格重载的接口解析问题
2019/09/11 Javascript
JS数组进阶示例【数组的几种函数用法】
2020/01/16 Javascript
[00:37]2016完美“圣”典风云人物:AMS宣传片
2016/12/06 DOTA
Python中使用不同编码读写txt文件详解
2015/05/28 Python
Python中http请求方法库汇总
2016/01/06 Python
python实现求最长回文子串长度
2018/01/22 Python
Python自然语言处理 NLTK 库用法入门教程【经典】
2018/06/26 Python
python实现自动登录
2018/09/17 Python
pytorch实现建立自己的数据集(以mnist为例)
2020/01/18 Python
解决Keras自带数据集与预训练model下载太慢问题
2020/06/12 Python
在tensorflow实现直接读取网络的参数(weight and bias)的值
2020/06/24 Python
全球知名的婚恋交友网站:Match.com
2017/01/05 全球购物
加拿大最大的相机店:Henry’s
2017/05/17 全球购物
Paul’s Boutique官网:英国时尚手袋品牌
2018/03/31 全球购物
老教师工作总结的自我评价
2013/09/27 职场文书
医学护理系毕业生求职信
2013/10/01 职场文书
经济管理专业毕业生自荐信范文
2014/01/02 职场文书
2014年百日安全生产活动总结
2014/05/04 职场文书
献爱心活动总结
2014/05/07 职场文书