().序言

在寫這個指南之前,先介紹一下Prototype主要是干嗎的,如果你比較關注ajax/javascipt方面的應用,你應該早就聽說過這個 javascript framework。 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 Ajax 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.createObject.extend,一個Try對象,函數綁定,number擴展,PeriodicalExecuter(周期性執行某個函數的功能)

string: String原型的擴展,為string添加了strip,escapeHTML等等好用的方法

enumerable: 枚舉類型(array, hash, range)的父類對象,提供枚舉類型的共同方法

array: Array原型的擴展,為array添加了indexOf、without等方法

hash: javascript提供了一個好用簡單的Hash實現

range: 繼承于enumerable,一個范圍(例如367)對象

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

不過要注意的是:要想很好的理解Prototype,應該首先理解一下javascript面向對象開發的一些知識以后的文章將對Prototype中具體的每個功能中的方法做一個詳細的介紹,包括作用,實例等Prototype官方網站是:http://prototype.conio.net/ ,目前發布版還只是1.4, 但是現在的1.5已經發生了很大的變化,而且很多基于prototype的庫使用的都是1.5的,所以強烈建議通過svn下載最新版代碼

 

().Prototype1.5 rc2)使用指南之base.js

base.js中包含下面的內容

類的創建與繼承:

Class.create(): 創建一個類,例如 person=Class.create()

Object.extend(destination, source): source中方法屬性copydestination(使用for property in source),需要注意的是,javascript中除了基本類型(Number, Boolean)外都是引用類型,所以這種copy一般只是copy引用而已,destinationsource還是指向同一個方法或對象屬性 (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): 調用objectinspect(如果定義了)toString方法,返回一個對象的字符串表示

Object.keys(object): 返回一個對象的所有屬性和方法名稱組成的數組, 例如Object.keys(document.body)

Object.values(object):返回一個對象的所有屬性和方法的值組成的數組, 例如Object.values(docuement)

Object.clone(object): 返回一個對象的clone版本,其實是執行Object.extent方法把object中的方法屬性copy到一個新對象中,然后返回這個對象

函數邦定:

定義了Function對象的兩個方法,bindbindAsEventListener,這兩個方法是一個函數的兩個方法,對于javac#程序員來說,看到這個也許感到很驚訝,因為在他們看來函數只是一個程序語句組織結構而已—>怎么還有方法,而且還可以擴展?這也是javascript等腳本語言相對于java等一個非常強大的功能,函數也是一個對象,函數名就是這個對象的名稱,只要你愿意,你也可以使用 new Function()來定義函數,所以為函數定義方法也就很正常不過了

這兩個函數的主要作用是為了解決使用javascript面向對象風格編程中this的引用問題,在javasctiptthis關鍵字始終指向調用該函數的對象或者指向使用call,apply方法指定的對象(具體這方面的知識可以自己google一下,以下系列對prototype的介紹也假設讀者對javascript語言比較熟悉了,如果不熟悉可以找本javascript權威指南這本書看看)要理解這個問題首先要理解始終指向這個問題,就是this這個關鍵字比較特殊,不能把他當成一般的變量名看待,最常見的一個錯誤就是在返回函數的調用中使用this,例如return function(){this.aMethod()}, 當你下次調用這個返回的匿名方法時,這個this引用的內容又指向了調用這個函數的對象了,記住的一點的this是個關鍵字,不是變量名,不會產生閉包

Number的擴展(注意num也可以看成對象,其實是在使用的時候系統自動打包成Number對象)

toColorPart:把數字轉換為可以用于表示color16進制值:例如 7.toColorPart()=>"07",28.toColorPart()=>"1C"

succ: 返回num++, 但不改變num本身的值,其實就是 return this1

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() 

 

()Prototype1.5 rc2)使用指南之string.js

下面介紹PrototypeString對象的擴展部分:

這部分主要為string對象添加了幾個很有用的方法:

strip(): 去掉字符串兩邊的空白, 例如" jj ".strip()返回"jj"

stripTags():去掉字符串中的html標簽

stripScripts(): 去掉字符串中的javascript代碼段

extractScripts(): 返回字符串中的javascript代碼,返回數組

evalScripts(): 執行字符串中的javascript代碼

escapeHTML():將字符串中的html代碼轉換為可以直接顯示的格式, 例如將< 轉化為 &lt; ,在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的屬性值

().Prototype1.5 rc2)使用指南之Enumerable.js

Enumerable是一個抽象對象(需要說明的是,javascript中并沒有類的概念,所指的類也就是一個函數,繼承一般指的是一個對象()將它的方法屬性copy(通過Object.extend, copy的是引用)到子類(函數)prototype屬性(一個對象)中)

Enumerable不能直接使用,它被很多枚舉類型(HashArrayRange等)所繼承,繼承的類型都要實現一個_each方法,提供具體類型的枚舉方法

Enumerable為其他子類提供了如下的方法:

each(iterator): iterator是一個函數對象, 這個方法調用具體類型的_each方法對自身包含的每個對象調用iterator,例如如果Enumerable具體指的是一個Arrayeg: 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對象的字符串表示



------君臨天下,舍我其誰------