Prototype是一个基础的javascript应用框架,先引用一段官方网站的介绍
Prototype is a JavaScript framework that aims to ease development of dynamic web applications. Featuring a unique, easy-to-use toolkit for class-driven development and the nicest <st1:place w:st="on"><st1:city w:st="on">Ajax</st1:city></st1:place> library around, Prototype is quickly becoming the codebase of choice for web application developers everywhere.
根据作者自己的介绍,Prototype的目的是为了更方便的开发javascript的应用,使用它可以更加方便简单的使用javascript编 程,开发出面向对象的javascript程序,Prototype中包含包含了一个功能强大好用的ajax框架,Prototype是一个基础性的框 架,很多更高层次的框架都以它为基础,例如scriptaculous效果库Prototype中包含一下几个部分:
base: Prototype中应用的基本功能,基本上其他所有部分都依赖于它,包括用于面向对象风格的Class.create和Object.extend,一 个Try对象,函数绑定,number扩展,PeriodicalExecuter(周期性执行某个函数的功能)等
string: 对String原型的扩展,为string添加了strip,escapeHTML等等好用的方法
enumerable: 枚举类型(array, hash, range等)的父类对象,提供枚举类型的共同方法
array: 对Array原型的扩展,为array添加了indexOf、without等方法
hash: 为javascript提供了一个好用简单的Hash实现
range: 继承于enumerable,一个范围(例如3—67)对象
ajax: 一个功能强大好用的ajax框架
dom: 对基于浏览器的开发提供了很好的跨浏览器封装,并添加很多强大的功能
selector: 提供了使用class,css等选择元素的功能
form: 关于表单的一些功能
event: 简单的夸平台事件封装
position: 提供了一些关于元素位置方面的功能
可以说Prototype就想一把瑞士军刀,为javascipt封装了很多通用的功能,大大简化了javascript应用的开发,给javascript开发人员增添了很大的信心,Prototype可以运行于以下平台,使用它再也不用各种跨平台等问题烦恼了* Microsoft Internet Explorer for Windows, version 6.0 and higher
* Mozilla Firefox 1.0/Mozilla 1.7 and higher
* Apple Safari 1.2 and higher <o:p> </o:p>
不过要注意的是:要想很好的理解Prototype,应该首先理解一下javascript面向对象开发的一些知识
以后的文章将对Prototype中具体的每个功能中的方法做一个详细的介绍,包括作用,实例等
Prototype官方网站是:http://prototype.conio.net/ ,目前发布版还只是1.4, 但是现在的1.5已经发生了很大的变化,而且很多基于prototype的库使用的都是1.5的,所以强烈建议通过svn下载最新版代码
base.js中包含下面的内容 类的创建与继承:Class.create(): 创建一个类,例如 person=Class.create()
Object.extend(destination, source): 把source中方法属性copy到destination(使用for property in source),需要注意的是,javascript中除了基本类型(Number, Boolean)外都是引用类型,所以这种copy一般只是copy引用而已,destination和source还是指向同一个方法或对象属性 (function array object)
在面向对象的编程中,一般通过Class.create新建一个类,如果这个类继承于另一个类,一般使用Object.extend (class.prototype, parentClass.prototype)或者Object.extend(class.prototype, aparentClassInstance) Object构造函数的扩展:Object是其他对象实例的构造函数(var a=new Object()),也是所有其他类的父类,对Object直接扩展(注意不是扩展Object.prototype,扩展 Object.prototype相当于添加实例方法)相当于为Object类添加静态方法Object.inspect(object): 调用object的inspect(如果定义了)或toString方法,返回一个对象的字符串表示
Object.keys(object): 返回一个对象的所有属性和方法名称组成的数组, 例如Object.keys(document.body)
Object.values(object):返回一个对象的所有属性和方法的值组成的数组, 例如Object.values(docuement)
Object.clone(object): 返回一个对象的clone版本,其实是执行Object.extent方法把object中的方法属性copy到一个新对象中,然后返回这个对象函数邦定:定义了Function对象的两个方法,bind和bindAsEventListener,这两个方法是一个函数的两个方法,对于java、c#程序员 来说,看到这个也许感到很惊讶,因为在他们看来函数只是一个程序语句组织结构而已—>怎么还有方法,而且还可以扩展? 这也是javascript等脚本语言相对于java等一个非常强大的功能,函数也是一个对象,函数名就是这个对象的名称,只要你愿意,你也可以使用 new Function(…)来定义函数,所以为函数定义方法也就很正常不过了这两个函数的主要作用是为了解决使用javascript面向对象风格编程中this的引用问题,在javasctipt中this关键字始终指向调用该函数的对象或者指向使用call,apply方法指定的对象(具体这方面的知识可以自己google一下,以下系列对prototype的介绍也假设读者对javascript语言比较熟悉了,如果不熟悉可以找本javascript权威指南这本书看看) 要理解这个问题首先要理解 始终指 向 这个问题,就是this这个关键字比较特殊,不能把他当成一般的变量名看待,最常见的一个错误就是在返回函数的调用中使用this,例如return function(){this.aMethod()}, 当你下次调用这个返回的匿名方法时,这个this引用的内容又指向了调用这个函数的对象了,记住的一点的this是个关键字,不是变量名,不会产生闭包 对Number的扩展(注意num也可以看成对象,其实是在使用的时候系统自动打包成Number对象): toColorPart:把数字转换为可以用于表示color的16进制值:例如 7.toColorPart()=>”07″,28.toColorPart()=>”1C”
succ: 返回num++, 但不改变num本身的值,其实就是 return this+1
times:对从0到这个数字轮流调用一个函数, 例如function a(n){docuement.write(n)}, 10.times(a), 将显示012345678910, 注意函数也是一个对象,而且与其他对象并没有实质的区别 Try对象: Try对象提供了一个很有趣的功能, 先看一下如下的代码:var Ajax = {
getTransport: function() {
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject(’Msxml2.XMLHTTP’)},
function() {return new ActiveXObject(’Microsoft.XMLHTTP’)} )
|| false;
}
}
Try对象提供了一个方法these, 这个方法接受一个函数类型的参数列表,然后轮流执行这些函数,当其中一个函数没有产生错误时,就停止执行,并且返回这个函数返回的值,自己慢慢体会吧 PeriodicalExecuter(周期性执行器)对象这个对象是对setInterval方法的简单封装,使用方法如下
var a=new PeriodicalExecuter(callback, frequency ) ,其中callback指要执行的函数名 frequency指 每次执行的时间间隔
要停止的话,调用这个对象的stop方法就可以了 a.stop()
下面介绍Prototype对String对象的扩展部分:
这部分主要为string对象添加了几个很有用的方法:
strip(): 去掉字符串两边的空白, 例如“ jj “.strip()返回“jj”
stripTags():去掉字符串中的html标签
stripScripts(): 去掉字符串中的javascript代码段
extractScripts(): 返回字符串中的javascript代码,返回数组
evalScripts(): 执行字符串中的javascript代码
escapeHTML():将字符串中的html代码转换为可以直接显示的格式, 例如将< 转化为 < ,在ie6中有bug,执行这个操作返回的字符串,将多个连在一起的空白变成了一个,所以很多换行什么的都被去掉了
unescapeHTML(): escapeHTML的反向过程
truncate(length, truncation): 截断,例如“abcdefghigkl”.truncate(10)返回abcdefg…, truncation默认为“…” toQueryParams(separator)/parseQuery(separator):将一个querystring转化为一个hash表(其实是一个对象,在javascript中对象可以当成hash表来用,因为对象的属性或方法可以通过object[propertyName]来访问)
toArray(): return this.split(’’), 转化为一个字符数组
camelize(): 将background-color的形式转化为backgroundColor形式,用在style/css中
capitalize(): 返回一个首字母大写的字符串
inspect(useDoubleQuotes): 返回字符串的表示形式, 例如“sdfj\”sfa”.inspect() 返回 “’sdfj”sfa’”
gsub(pattern, replacement):pattern是一个正则表达式,replacement是 一个函数(或者是一个template字符串),对于字符串中每个匹配pattern的部分使用replacement处理,然后将 replacement返回的值将原来匹配的部分替换掉,例如“skdjfAsfdjkAdk”.gsub(/A/,function(match) {return match[0].toLowerCase()}), 将字符串所有的A转化为a, 注意pattern中不要添加g选项,因为gsub会递归的执行match方法
sub(pattern, replacement, count) :gsub的另一种形式,不过可以设置执行的次数
scan(pattern, iterator): 跟gsub差不多,但是返回的是字符串本身,也就是说对于pattern中的每个匹配执行iterator,但是不返回替换的字符串“skdjfAsfdjkAdk”.gsub(/A/,function(){alert ‘have a A’})
underscore(): ‘borderBottomWidth’.underscore() -> ‘border_bottom_width’
dasherize(): ‘Hello_World’.dasherize() -> ‘Hello-World’
Template模板类:
使用方法:
var template = new Template(replacement, pattern);
template.evaluate(object) 有点像php中的模板,默认(没有提供pattern)将{propertyName}形式的东西替换了object的属性值
Enumerable是一个抽象对象(需要说明的是,javascript中并没有类的概念,所指的类也就是一个函数,继承一般指的是一个对象(父)将它 的方法属性copy(通过Object.extend, copy的是引用)到子类(函数)的prototype属性(一个对象)中)Enumerable不能直接使用,它被很多枚举类型(Hash、Array、Range等)所继承,继承的类型都要实现一个_each方法,提供具体类型的枚举方法Enumerable为其他子类提供了如下的方法:
each(iterator): iterator是一个函数对象, 这个方法调用具体类型的_each方法对自身包含的每个对象调用iterator,例如如果Enumerable具体指的是一个Array,eg: var a=[2,3,4], 则a.each(iterator)方法将依次调用iterator(2,0) ,iterator(3,1), iterator(4,3),其中第二个参数指的是索引。这个方法几乎在Enumerable中的每个方法中都要用到
eachSlice(number, iterator):将Enumerable 类型对象每个每个按照number分开,例如[1,2,3,4,5].eachSlice(3)=>[[1,2,3],[4,5]], 没有提供iterator, 则iterator=Prototype.K: function(k){return k},Prototype中的很多iterator默认值都是这个,或者是Prototype.emptyFunction: function() {},其实实际上返回的是[iterator([1,2,3]),iterator([4,5])]
all(iterator): 对Enumerable类型中的每个值调用iterator,如果其中有一个返回false,则返回false,否则返回true,相当于判断是否每个值执行iterator都是“true”
any(iterator): 跟all相反,判断是否每个值都是“false”(是否有一个值是true)
collect(iterator)/map: 对每个值调用iterator,将结果组成一个新的数组返回
detect(iterator)/find: 对每个值调用iterator,如果有一个不为false,则返回这个执行iterator后不为false的值(不是返回执行iterator后的值),相当于找出第一个真值
findAll(iterator)/select: 相当于detect, 但是找出所有的真值,返回一个数组
grep(pattern, iterator):返回所以符合pattern的值,iterator提供的话,则返回执行iterator的值
include(object)/member: 数组中是否包含object
inGroupsOf(number, fillWith): eachSlice的变异版本,按照number将对象分开,如果分开后的数组的最后一个值的length小于number, 则用fillwith填充, 例如[1,2,3,4,5].inGroupsOf(3)=>[[1,2,3],[4,5,null]]
inject(memo, iterator): 注入
invoke(method): 调用
max(iterator): 最大值
min(iterator): 最小值
partition(iterator): 分离
pluck(property): 采集
reject(iterator): 不合格的产品, 于findAll相反
sortBy(iterator): 根据iterator排序,如果调用的对象是Array的话,直接调用内置的sort(iterator)就行了
toArray()/entries: 将调用对象的每个值组成一个数组返回
zip(): 例如[2,3,4].zip([5,6,7])=>[[2,5],[3,6],[4,7]], 如果最后一个参数类型为function,将返回[iterator([2,5]),iterator([3,6]),iterator([4,7])],
inspect(): Enumerable对象的字符串表示NND的,原来Enumerable有这么多函数,感觉作者是不是学习Ruby太过了,把什么方法都往Prototype上挪,搞的我们学习的也辛苦, Prototype文件也变得越来越大,浪费带宽啊 唉,发现其中很多函数越解释越难懂,大家还是多多看看源代码理解吧,偶的文字表达能力真的不乍的,有的实在不知道怎么表达, 希望大家还是只是把本文当成一个不正规的参考,有什么问题还是看源代码理解,不然误导了你我可不负责啊
$A = Array.from(iterable): 将iterable转化为数组,如果iterable定义了toArray方法,就调用这个方法,否则利用iterable的length属性进行枚举, 如果iterable没有length属性的话就返回空数组[] Array对象除了扩展Enumerable对象的方法外,另外扩展了如下的几个方法,注意以下方法除了clear外都不改变原来数组,而是返回一个新数组:
clear(): 清除数组,利用arr.length=0first(): 返回第一个元素 last():返回最后一个元素compact(): 去除数组中值为null或undefined的元素flatten(): 将数组扁平化,例如[3,4,[6,7]]变为[3,4,6,7] without(): 去除指定的元素, 可以指定多个值, 例如[4,56,7,8].without(4,7) 返回[56,8]indexOf(object): 返回指定的元素在数组中的索引,不包含则返回-1reverse(inline):Array内置函数reverse的增强,当inline为true时,跟内置的reverse函数效果一样,改变原数组的值,否则不改变原来的值reduce(): 如果数组只有一个元素,则返回这个元素,否则返回数组本身 uniq(): 返回没有重复元素的数组clone(): 返回一个跟数组相同的数组,Array中的toArray方法覆盖了Enumerable中的toArray方法,指向了这个方法 inspect(): 跟数组的toString方法类似,返回对象的字符串表示,例如[2,3].inspect() 返回 “[2,3]”
<o:p> </o:p>
Hash对象(关联数组)是Prototype新建的一个对象,要创建一个Hash对象可以调用$H(object)方法,使用这个方法将生成一个基于 object对象的Hash对象,生成的Hash对象将object的属性名作为key,将object的属性值最为键值,因为javascript本身 的特点(对象本身就是关联数组) ,所以实现Hash也很简单,Prototype中的Hash只是javascript的关联数组(对象)而已
Prototype中的Hash对象继承自Enumerable对象,所以也具有Enumerable对象的所有属性和方法,另外它具有以下的方法:
keys(): 返回hash的键值数组
values(): 返回值得数组
merge(hash): 合并两个hash
toQueryString(): 跟string的toQueryParams方法想法,将hash转化为一个querystring, 会调用encodeURIComponent对键和值进行编码
inspect(): hash的字符串表示 因为hash只是javascript的一个普通的对象而已,所以添加一个键值对使用: hash[key]=value就可以了,删除一个键值对使用 detele hash[key]就可以了