摘要:《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>