1. 用JavaScript實作類別
JavaScritpt沒有專門的機制實作類別,這裡是藉助它的函數允許嵌套的機制來實作類別的。一個函數可以包含變數,又可以包含其它函數,這樣,變數可以作為屬性,內部的函數就可以作為成員方法了。因此外層函數本身就可以作為一個類了。如下:
複製代碼 代碼如下:function myClass()
{
//此處相當於建構函式
}
這裡 myClass就是一個類。其實可以把它看成類的建構函式。至於非建構函式的部分,以後會詳細描述。
2. 如何獲得一個類的執行個體
實現了類就應該可以獲得類的執行個體,JavaScript提供了一個方法可以獲得對象執行個體。即 new操作符。其實JavaScript中,類和函數是同一個概念,當用new操作一個函數時就返回一個對象。如下:
var obj1 = new myClass();
3. 對象的成員的引用
在JavaScript中引用一個類的屬性或方法的方法有以下三種。
1> 點號操作符
這是一種最普遍的引用方式,就不累贅。即如下形式:
對象名.屬性名稱;
對象名.方法名;
2> 方括弧引用
JavaScript中允許用方括弧引用對象的成員。如下:
對象名["屬性名稱"];
對象名["方法名"];
這裡方括弧內是代表屬性或方法名的字串,不一定是字串常量。也可以使用變數。這樣就可以使用變數傳遞屬性或方法名。為編程帶來了方便。在某些情況下,代碼中不能確定要調用那個屬性或方法時,就可以採用這種方式。否則,如果使用點號操作符,還需要使用條件判斷來調用屬性或方法。
另外,使用方括弧引用的屬性和方法名還可以以數字開頭,或者出現空格,而使用點號引用的屬性和方法名則遵循標示符的規則。但一般不提倡使用非標示符的命名方法。
3> 使用eval函數
如果不希望使用變數傳遞變數或方法名,又不想使用條件判斷,那麼eval函數是一個好的選擇。eval接收一個字串類型的參數,然後將這個字串作為代碼在上下文中執行,返回執行的結果。這裡正是利用了eval的這一功能。如下:
alert(eval("對象名." + element.value));
4. 對對象屬性,方法的添加、修改和刪除操作
JavaScript中,在產生對象之後還可以為對象動態添加、修改和刪除屬性和方法,這與其它物件導向的語言是不同的。
1> 添加屬性和方法
先建立一個對象,Null 物件建立後沒有任何屬性和方法,然而我們可以在代碼中建立。 複製代碼 代碼如下:var obj1 = new Object();
//添加屬性
obj1.ID = 1;
obj1.Name = "johnson";
//添加方法
obj1.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
2> 修改屬性與方法
與添加屬性和方法類似,例如接著上面的例子: 複製代碼 代碼如下:// 修改屬性
obj1.ID = 2;
obj1.Name = "Amanda";
// 修改方法
obj1.showMessage = function()
{
alert("ID: " + this.ID");
}
3> 刪除屬性與方法
直接將要刪除的屬性或方法賦值為undefined即可: 複製代碼 代碼如下:obj1.ID = 1;
obj1.Name = undefined;
obj1.showMessage = undefined;
5. 建立無類型對象。
類似於C#3.0裡的Anonymous Types,JavaScript 也可以建立無類型的對象。形式如下: 複製代碼 代碼如下:var obj1 = {};
var obj2 =
{
ID: 1,
Name: "Johnson",
showMessage: function()
{
alert("ID: " + this.ID + "Name: " + this.Name);
}
}
這裡定義了兩個無類型的對象,obj1和obj2。其中obj1是一個Null 物件。obj2包括兩個屬性ID, Name和一個方法showMessage。每個屬性和方法用逗號分割。屬性(方法)名和其值之間用分號分割。
用這種方式建立屬性方法時,也可以用字串定義屬性方法的名字。如: 複製代碼 代碼如下:var obj2 =
{
"ID" : 1,
"Name": "Johnson"
}
6. prototype
每個函數對象都具有一個子物件prototype,因為函數也可以表示類,所以prototype表示一個類的成員的集合。當new 一個對象時,prototype對象的成員都會被執行個體化成對象的成員。先看一個例子: 複製代碼 代碼如下:function myClass()
{ }
myClass.prototype.ID = 1;
myClass.prototype.Name = "johnson";
myClass.prototype.showMessage = function()
{
alert("ID: " + this.ID + "Name: " + this.Name);
}
var obj1 = new myClass();
obj1.showMessage();
使用prototype對象建立類有一個好處。如果將所有的成員直接寫在類的聲明中,如下: 複製代碼 代碼如下:function myClass()
{
//添加屬性
this.ID = 1;
this.Name = "johnson";
//添加方法
this.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
}
var obj1 = new myClass();
var obj2 = new myClass();
在上面的代碼中,定義了一個類myClass,在類中直接定義了兩個屬性和一個方法。然後執行個體化了兩個對象,這裡的兩個屬性和一個方法,每建立一次myClass對象都會被建立一次,浪費了記憶體空間。而用prototype以後就可以解決這個問題,每new一個函數時,其prototype對象的成員都會自動賦給這個對象,當new多個對象時不會重複建立。
由於prototype的初始化發生在函數體執行之前,用以下代碼可以證明: 複製代碼 代碼如下:function myClass()
{
//此處相當於建構函式
this.ID = 1;
this.Name1 = this.Name;
this.showMessage();
}
myClass.prototype.Name = "johnson";
myClass.prototype.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
var obj1 = new myClass();
執行以上代碼可以發現當new這個類型的對象時,即彈出了對話方塊。
最後只得一提的是,prototype有一個方法,在物件導向的設計中用得到。即:constructor屬性,是對建構函式的調用,這裡的建構函式即上文提到的類的聲明裡的代碼。如: 複製代碼 代碼如下:function myClass()
{
//此處相當於建構函式
alert("this is in constructor");
}
myClass.prototype.constructor();
var obj1 = new myClass();
執行以上代碼你會發現對話方塊彈出了兩次。由此可見,prototype可專門用於設計類的成員,實際上在JavaScript物件導向的設計中,很多時候都會用到prototype。