Basic - 基礎代碼

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

Source View - 源碼解析

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

Field & Function Reference - 屬性方法一覽

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

Analysis & Usage - 分析與使用

Extension - 擴展

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


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



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