《ASP.NET AJAX 經典講座》逐步教學 #2:使用 JavaScript 定義類別、繼承類別

摘要:《ASP.NET AJAX 經典講座》逐步教學 #2:使用 JavaScript 定義類別、繼承類別

本書第 2 章的 p.59--63 示範如何以 JavaScript 定義類別及衍生類別,其中提到定義類別的方式有兩種:closure 和 prototype,這裡的範例是採用 prototype 的方式。除此之外,這裡也簡單示範使用 traceDump 來顯示物件的內容,這個小工具可以節省一些除錯的時間。

此範例定義了兩個類別: Person 及 Citizen。其中 Citizen 繼承自 Person 類別。兩者的關係及成員請參考以下類別圖:

這張圖是用 VS2005 拉出來的,雖然它會產生對應的 C#/VB code,但這裡我們要用 JavaScript 做出跟 C#/VB 等價的類別。

步驟

  1. 從 Visual Studio 2005 中開啟既有之 AJAX-enabled 網站,在網站中加入一個新網頁,命名為 JsClass.aspx。
  2. 從 Toolbox 拉一個 ScriptManager 至網頁上(少了這個控制項,AJAX Client Library 即無法運作,許多 JavaScript 擴充語法也無法使用)。
  3. 定義基礎類別 Person,參見程式列表 1
  4. 從 Person 類別繼承一個新的子類別:Citizen。參見程式列表 2
  5. 類別定義完畢之後,接著寫點測試的程式碼。首先再網頁上放一個 HTML Button,然後撰寫其 onclick 事件處理常式。在此處理常式中,我們要建立 Citizen 物件、設定其屬性,然後用 traceDump 把物件的內容 dump 在網頁上。參考程式列表 3
  6. traceDump 需要一個名為 "traceConsole" 的 <textArea> 元素,用來顯示除錯資訊。因此還要在網頁上放一個 <textArea>,或者 TextBox 伺服器控制項。參考程式列表 4
  7. 在瀏覽器中檢視網頁的執行結果。執行結果的畫面請參考本書 p.87 的圖 2-2。

Note:

  • 存取 JavaScript 類別的屬性時,必須透過 accessor(即 get_XXX 和 set_XXX 方法)。
  • traceDump 的詳細說明參見本書的 p.86。

程式列表 1:Person 類別

<script type="text/javascript">

// 註冊命名空間
Type.registerNamespace("IntroAjax");

// 建構函式 (constructor)
IntroAjax.Person = function IntroAjax$Person(firstName, lastName)
{
    this._firstName = firstName;
    this._lastName = lastName;
}

// 定義類別原型
IntroAjax.Person.prototype = 
{
    ToString: IntroAjax$Person$ToString,
    get_FirstName: IntroAjax$Person$get_FirstName,
    set_FirstName: IntroAjax$Person$set_FirstName,
    get_LastName: IntroAjax$Person$get_LastName,
    set_LastName: IntroAjax$Person$set_LastName
}

// 定義成員方法:ToString
function IntroAjax$Person$ToString() 
{
    return this._lastName + ", " + this._firstName;
}


// 定義屬性:FirstName  
IntroAjax.Person.prototype.get_FirstName =  
    function IntroAjax$Person$get_FirstName() 
    {  
        // 如果參數個數不正確,則引發錯誤 
        if (arguments.length !== 0)  
            throw Error.parameterCount (); 
        return this._firstName; 
    }

IntroAjax.Person.prototype.set_FirstName =  
    function IntroAjax$Person$set_FirstName(value) 
    { 
        // 檢查參數
        var e = Function._validateParams(arguments,  
                    [{name: "value", type: String}]);        
        if (e)  
            throw e; 
        this._firstName = value; 
    } 
 
// 定義屬性:LastName
IntroAjax.Person.prototype.get_LastName =  
    function IntroAjax$Person$get_LastName() 
    {  
        if (arguments.length !== 0)  
            throw Error.parameterCount();

        return this._lastName; 
    } 

IntroAjax.Person.prototype.set_LastName =  
    function IntroAjax$Person$set_LastName(value) { 
        var e = Function._validateParams(arguments,  
                    [{name: "value", type: String}]); 
        
        if (e)  
            throw e; 
        this._lastName = value; 
    } 

// 註冊類別
IntroAjax.Person.registerClass("IntroAjax.Person");

</script>

程式列表 2:Citizen 類別 

//==================================================================
// 定義子類別:Citizen
IntroAjax.Citizen = function IntroAjax$Citizen(firstName, lastName, id) { // 初始化父類別成員. IntroAjax.Citizen.initializeBase(this, [firstName, lastName]); this._id = id; this._address = ""; } // 定義原型 IntroAjax.Citizen.prototype = { ToString: IntroAjax$Citizen$ToString, get_ID: IntroAjax$Citizen$get_ID, set_ID: IntroAjax$Citizen$set_ID, get_Address: IntroAjax$Citizen$get_Address, set_Address: IntroAjax$Citizen$set_Address } function IntroAjax$Citizen$ToString() { var temp = IntroAjax.Citizen.callBaseMethod(this, 'ToString'); temp += " [" + this._id + "]"; return temp; } // 定義屬性:ID IntroAjax.Citizen.prototype.get_ID = function IntroAjax$Citizen$get_ID() { // 如果引數個數不正確,則引發錯誤 if (arguments.length !== 0) throw Error.parameterCount (); return this._id; } IntroAjax.Citizen.prototype.set_ID = function IntroAjax$Citizen$Set_ID(value) { // 檢查參數 var e = Function._validateParams(arguments, [{name: "value", type: String}]); if (e) throw e; this._id = value; } // 定義屬性:Address IntroAjax.Citizen.prototype.get_Address = function IntroAjax$Citizen$get_Address() { // 如果參數個數不正確,則引發錯誤 if (arguments.length !== 0) throw Error.parameterCount (); return this._address; } IntroAjax.Citizen.prototype.set_Address = function IntroAjax$Citizen$set_Address(value) { // 檢查參數 var e = Function._validateParams(arguments, [{name: "value", type: String}]); if (e) throw e; this._address = value; } // 註冊類別 (注意:需指明父類別為 Person) IntroAjax.Citizen.registerClass("IntroAjax.Citizen", IntroAjax.Person);
程式列表 3:用戶端按鈕的事件處理常式
function Button1_onclick() 
{
    var obj = new IntroAjax.Citizen("Michael", "Tsai", "1234");
    obj.set_Address("台北縣樹林市厚德路");
    
    Sys.Debug.traceDump(obj);
}

程式列表 4:用來顯示除錯資訊的按鈕及文字區域標籤

<input id="Button1" type="button" value="顯示 Citizen 物件內容)" onclick="return Button1_onclick()" />


<br />


<asp:TextBox ID="traceConsole" runat="server" Height="104px" TextMode="MultiLine"


        Width="304px"></asp:TextBox>