Basic - 基礎(chǔ)代碼

在開始所有的Prototype學(xué)習(xí)之旅之前,我們首先對Prototype中最常用的一些公用函數(shù)做一些研究,這些JavaScript函數(shù)將貫穿整個Prototype框架,熟練使用它們不僅有助于我們學(xué)習(xí)Prototype框架,同時也為我們自己編寫JavaScript應(yīng)用提供了獨特的思路。

Source View - 源碼解析

var Prototype = {     // 定義一個Prototype對象,封裝了一些簡單的靜態(tài)函數(shù)和變量
Version: '1.5.0_rc1',     // 定義當(dāng)前Prototype框架的版本號
ScriptFragment: '(?:
)((\n|\r|.)*?)(?:<\/script>)',   // 返回一個正則表達式,判斷是否為Script塊
emptyFunction: function() {},    // 返回一個空的函數(shù), 該函數(shù)什么都不做, 在編寫一些復(fù)雜流程中會使用此功能
K: function(x) {return x}     // 返回參數(shù)本身, 在編寫一些復(fù)雜流程中會使用此功能
}
/*****************************************************************************************************************/
function $() {   // 一個根據(jù)id讀取對象的快捷函數(shù), 根據(jù)id返回所對應(yīng)的對象
var results = [], element;
for (var i = 0; i < arguments.length; i++) { // 可以接受多個參數(shù), 返回由每個id所對應(yīng)的對象構(gòu)成的數(shù)組
element = arguments[i];
if (typeof element == 'string')    // 可以接受非string參數(shù),直接返回對象本身
element = document.getElementById(element);  // 通過DOM操作讀取對象
results.push(Element.extend(element)); // 參見Element.extend的解析, 為返回的對象添加了一些額外特性,并壓入到結(jié)果數(shù)組中
}
return results.reduce(); // 根據(jù)參數(shù)的個數(shù)返回對象或者對象數(shù)組
}
/*****************************************************************************************************************/
var Abstract = new Object();  // 定義了一個全局的對象, 可以理解為一個命名空間, 成為一個抽象基類
/*****************************************************************************************************************/
var Try = {
these: function() {  // 一個靜態(tài)的函數(shù), 接受多個函數(shù)作為參數(shù), 依次執(zhí)行并返回第一個成功執(zhí)行的函數(shù)的結(jié)果
var returnValue;
for (var i = 0; i < arguments.length; i++) {
var lambda = arguments[i];   // 每個參數(shù)都是一個將被執(zhí)行的函數(shù)
try {
returnValue = lambda();    // 執(zhí)行函數(shù)并記錄返回值
break;                     // 第一次成功執(zhí)行后, 即退出
} catch (e) {}   // 捕獲每個函數(shù)執(zhí)行過程中的異常
}
return returnValue;
}
}
/*****************************************************************************************************************/
var PeriodicalExecuter = Class.create();  // 定義一個定時器, 重復(fù)執(zhí)行某一函數(shù)
PeriodicalExecuter.prototype = {
initialize: function(callback, frequency) {  // 構(gòu)造函數(shù), 定義需要重復(fù)執(zhí)行的函數(shù)和執(zhí)行周期
this.callback = callback;      // 需要重復(fù)執(zhí)行的函數(shù)
this.frequency = frequency;    // 重復(fù)執(zhí)行的周期, 單位是秒
this.currentlyExecuting = false;   // 是否當(dāng)前執(zhí)行標(biāo)志
this.registerCallback();    // 調(diào)用重復(fù)執(zhí)行的函數(shù)
},
registerCallback: function() { // 調(diào)用window.setInterval函數(shù)完成重復(fù)執(zhí)行, 返回一個標(biāo)志留作被stop函數(shù)調(diào)用, 以停止定時器
// 第一個參數(shù)巧妙地使用了bind方法, 將this作為bind的參數(shù), 這樣onTimeEvent方法內(nèi)部可以通過this獲取當(dāng)前對象的引用
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
stop: function() {
if (!this.timer) return;   // 通過setInterval函數(shù)的返回值來判斷是否當(dāng)前執(zhí)行
clearInterval(this.timer);   // 當(dāng)前執(zhí)行時, 調(diào)用clearInterval方法來中止當(dāng)前的執(zhí)行
this.timer = null;    // 將當(dāng)前執(zhí)行的標(biāo)志設(shè)置為null
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {  // 判斷是否當(dāng)前執(zhí)行, 否則跳過, 相當(dāng)于一個同步信號量
try {
this.currentlyExecuting = true;  // 設(shè)置是否當(dāng)前執(zhí)行的標(biāo)志
this.callback(this);   // 調(diào)用callback完成真正的函數(shù)執(zhí)行
} finally {
this.currentlyExecuting = false;  // 無論是否成功執(zhí)行, 最終設(shè)置當(dāng)前執(zhí)行標(biāo)志為false
}
}
}
}

Field & Function Reference - 屬性方法一覽

Prototype ( 靜態(tài) )
Method / Property Kind Arguments Description
Version 靜態(tài)屬性  / 表示Prototype框架的版本號
ScriptFragment 靜態(tài)屬性  / 表示script代碼段的正則表達式
emptyFunction 靜態(tài)方法  / 返回一個什么都不做的空函數(shù)
K 靜態(tài)方法 任意對象 返回傳入的參數(shù)
$() ( 靜態(tài) )
Method / Property Kind Arguments Description
$() 靜態(tài)方法 string或者任意對象, 參數(shù)數(shù)量不限 根據(jù)參數(shù)的類型和數(shù)量返回DOM操作的結(jié)果, 傳入的參數(shù)為string時,返回document.getElementById所讀取的對象; 傳入的參數(shù)為非string類型的對象時, 直接返回參數(shù)本身; 當(dāng)參數(shù)個數(shù)是1個時, 直接返回上述操作所得的結(jié)果; 當(dāng)參數(shù)個數(shù)大于1個時, 將每個參數(shù)操作的結(jié)果組成一個對象數(shù)組返回
Abstract ( 靜態(tài) )
Method / Property Kind Arguments Description
Abstract  / 一個全局的對象, 可以理解為一個命名空間, 成為一個抽象基類
Try ( 靜態(tài) )
Method / Property Kind Arguments Description
these 靜態(tài)方法 多個有待依次執(zhí)行的函數(shù) 返回第一個成功執(zhí)行的函數(shù)的執(zhí)行結(jié)果
PeriodicalExecuter ( 實例 )
Method / Property Kind Arguments Description
callback 屬性  / 構(gòu)造函數(shù)實例化時初始化的屬性, 定義定時器重復(fù)執(zhí)行時真正需要調(diào)用的函數(shù)
frequency 屬性(Number)  / 構(gòu)造函數(shù)實例化時初始化的屬性, 定義定時器重復(fù)執(zhí)行的時間間隔
currentlyExecuting 屬性(Boolean)  / 在整個定時器執(zhí)行過程中表示是否當(dāng)前執(zhí)行的標(biāo)志, 可以作為執(zhí)行過程中的同步信號量
timer 屬性  / 一個內(nèi)部變量, 在registerCallback方法調(diào)用window.setInterval時記錄該函數(shù)的返回值, 用以給stop方法使用
registerCallback 方法  / 在構(gòu)造函數(shù)初始化完成時調(diào)用執(zhí)行, 也可以直接調(diào)用該函數(shù)啟動定時器, 在函數(shù)內(nèi)部通過調(diào)用window.setInterval方法完成定時器功能
stop 方法 this.timer, 即重復(fù)執(zhí)行時調(diào)用setInterval的返回值 用于暫停定時器, 通過實例變量調(diào)用完成
onTimerEvent 方法  / 一個內(nèi)部方法, 真正調(diào)用callback完成函數(shù)執(zhí)行

Analysis & Usage - 分析與使用

Extension - 擴展

$()為我們提供了一個快捷的方式,通過id來讀取一個對象,從而避免了我們在編寫JavaScript代碼時的重復(fù)而又冗長的代碼段。然而,在某些情況下,我們需要通過對象的name屬性來讀取對象,并對對象進行一定的操作,此時,$()方法就顯得有些力不從心了。因而在這里,我針對這種需求,并模仿$()方法,實現(xiàn)了一個通過name來讀取對象的函數(shù)。


事實上,getElementsByName()已經(jīng)幫我們解決了大多數(shù)的問題。由于name在HTML的document中可以不唯一,因而我們需要對此進行簡單的處理,當(dāng)name唯一時,直接返回單一對象;當(dāng)name不唯一時,返回一個數(shù)組(這已經(jīng)與getElementsByName()本身的含義不同了,當(dāng)然這僅僅是為了方便編程而已)。



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