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