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 字符串转化成数字的代码
Jun 29 Javascript
学习从实践开始之jQuery插件开发 菜单插件开发
May 03 Javascript
HTML5之lang属性与dir属性的详解
Jun 19 Javascript
javascript获取当前的时间戳的方法汇总
Jul 26 Javascript
React.js入门学习第一篇
Mar 30 Javascript
原生JS京东轮播图代码
Mar 22 Javascript
vue升级之路之vue-router的使用教程
Aug 14 Javascript
微信小程序引用iconfont图标的方法
Oct 22 Javascript
Vue中对iframe实现keep alive无刷新的方法
Jul 23 Javascript
javascript实现点亮灯泡特效示例
Oct 15 Javascript
微信小程序indexOf的替换方法(推荐)
Jan 14 Javascript
vue中如何自定义右键菜单详解
Dec 08 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 curl模拟浏览器抓取网站信息
2013/10/28 PHP
PHP date()函数警告: It is not safe to rely on the system解决方法
2014/08/20 PHP
分析PHP中单双引号的误区和双引号小隐患
2016/07/19 PHP
PHP单元测试框架PHPUnit用法详解
2019/01/23 PHP
搭建PhpStorm+PhpStudy开发环境的超详细教程
2020/09/17 PHP
JavaScript语言中的Literal Syntax特性分析
2007/03/08 Javascript
JavaScript高级程序设计 读书笔记之八 Function类及闭包
2012/02/27 Javascript
JS数组去重与取重的示例代码
2014/01/24 Javascript
JS简单实现String转Date的方法
2016/03/02 Javascript
JavaScript组合模式学习要点
2016/08/26 Javascript
JS实现的驼峰式和连字符式转换功能分析
2016/12/21 Javascript
JS实现的DIV块来回滚动效果示例
2017/02/07 Javascript
Vue关于数据绑定出错解决办法
2017/05/15 Javascript
如何编写一个完整的Angular4 FormText 组件
2017/11/18 Javascript
详解关于微信setData回调函数中的坑
2019/02/18 Javascript
JavaScript实现表单验证功能
2020/12/09 Javascript
[44:50]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第二局
2016/02/26 DOTA
Python接收Gmail新邮件并发送到gtalk的方法
2015/03/10 Python
Django中的“惰性翻译”方法的相关使用
2015/07/27 Python
Python标准库之collections包的使用教程
2017/04/27 Python
Python实现单词翻译功能
2017/06/06 Python
利用标准库fractions模块让Python支持分数类型的方法详解
2017/08/11 Python
Python之csv文件从MySQL数据库导入导出的方法
2018/06/21 Python
Python快速查找list中相同部分的方法
2018/06/27 Python
Python字符串的全排列算法实例详解
2019/01/07 Python
树莓派极简安装OpenCv的方法步骤
2019/10/10 Python
Python numpy.zero() 初始化矩阵实例
2019/11/27 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
2020/03/20 Python
欧洲最大的品牌水上运动服装和设备在线零售商:Wuituit Outlet
2018/05/05 全球购物
Yahoo-PHP面试题4
2012/05/05 面试题
电气自动化大学生求职信
2013/10/16 职场文书
法律专业应届本科毕业生求职信
2013/10/25 职场文书
烹饪自我鉴定
2014/03/01 职场文书
委托书英文
2015/01/28 职场文书
2015年上半年党建工作总结
2015/03/30 职场文书
flex布局中使用flex-wrap实现换行的项目实践
2022/06/21 HTML / CSS