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 相关文章推荐
Ext JS Grid在IE6 下宽度的问题解决方法
Feb 15 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
May 08 Javascript
禁用页面部分JavaScript不是全部而是部分
Sep 03 Javascript
浅析jQuery EasyUI中的tree使用指南
Dec 18 Javascript
AngularJS仿苹果滑屏删除控件
Jan 18 Javascript
JavaScript模拟数组合并concat
Mar 06 Javascript
JS+CSS实现的漂亮渐变背景特效代码(6个渐变效果)
Mar 25 Javascript
Bootstrap插件全集
Jul 18 Javascript
jQuery实现简单的滑动导航代码(移动端)
May 22 jQuery
Vue数据双向绑定的深入探究
Nov 27 Javascript
vue框架中props的typescript用法详解
Feb 17 Javascript
javascript实现移动端上传图片功能
Aug 18 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自动加载的两种实现方法
2010/06/21 PHP
PHP中require和include路径问题详解
2014/12/25 PHP
PHP+JS三级菜单联动菜单实现方法
2016/02/24 PHP
PHP面向对象学习之parent::关键字
2017/01/18 PHP
PHP实现微信提现功能
2018/09/30 PHP
用jscript实现列出安装的软件列表
2007/06/18 Javascript
为JS扩展Array.prototype.indexOf引发的问题探讨及解决
2013/04/24 Javascript
JS仿百度搜索自动提示框匹配查询功能
2013/11/21 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
JavaScript的Backbone.js框架环境搭建及Hellow world示例
2016/05/07 Javascript
省市二级联动小案例讲解
2016/07/24 Javascript
利用bootstrapValidator验证UEditor
2016/09/14 Javascript
jQuery复合事件用法示例
2017/06/10 jQuery
vue单页应用中如何使用jquery的方法示例
2017/07/27 jQuery
深入学习TypeScript 、React、 Redux和Ant-Design的最佳实践
2019/06/17 Javascript
angularjs请求数据的方法示例
2019/08/06 Javascript
云服务器部署Node.js项目的方法步骤(小白系列)
2020/03/23 Javascript
[01:16:01]VGJ.S vs Mski Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
python中的函数用法入门教程
2014/09/02 Python
Python类的定义、继承及类对象使用方法简明教程
2015/05/08 Python
Python简单实现Base64编码和解码的方法
2017/04/29 Python
python如何实现反向迭代
2018/03/20 Python
Python 在字符串中加入变量的实例讲解
2018/05/02 Python
对pandas replace函数的使用方法小结
2018/05/18 Python
Python3 修改默认环境的方法
2019/02/16 Python
Python使用Beautiful Soup爬取豆瓣音乐排行榜过程解析
2019/08/15 Python
解决tensorboard多个events文件显示紊乱的问题
2020/02/15 Python
Python把图片转化为pdf代码实例
2020/07/28 Python
一款纯css3实现的响应式导航
2014/10/31 HTML / CSS
Bobbi Brown芭比波朗美国官网:化妆师专业彩妆保养品品牌
2016/08/18 全球购物
Ralph Lauren意大利官方网站:时尚界最负盛名的品牌之一
2018/10/18 全球购物
一加手机美国官方网站:OnePlus美国
2019/09/19 全球购物
简单叙述一下MYSQL的优化
2016/05/09 面试题
吨的认识教学反思
2014/04/27 职场文书
工程项目经理任命书
2014/06/05 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书