5 自訂類和對象
5.1 Factory 方法
在ECMAScript中建立Factory 方法,返回一個特定類型的對象,以此實現代碼的簡潔適用。
function createFruit() {
var tempFruit = new Object;
tempFruit.name = "apple";
tempFruit.number = 5;
tempFruit.showName = function() {
alert(this.name);
};
return tempFruit;
}
var Fruit1 = creatFruit();
var Fruit2 = creatFruit();
在createFruit()中可以加入形參來傳入參數的值。隨著ECMAScript不斷被正常化,這種建立對象的方法已不再流行,一部分原因是文法上的,一部分原因是功能上的,如每個對象的執行個體都擁有屬於自己的showName方法,給記憶體管理帶來一定的開銷。
5.2 建構函式
選擇一個類名,第一個字母大寫,該類名即是建構函式的名稱。建立一個建構函式和Factory 方法比較類似,不同的是需要使用關鍵字new來建立對象的引用。使用建構函式的方式來建立對象和使用Factory 方法有著相同的弊端。
function Fruit(name, number) {
this.name = name;
this.number = number;
this.showName = function() {
alert(this.name);
};
}
var Fruit1 = new Fruit("apple", 5);
var Fruit2 = new Fruit("pear", 3);
5.3 使用 Prototype
使用prototype屬性可以用來建立新的對象,首先需要一個空的建構函式建立類的名稱,然後所有的屬性和方法都直接分配到prototype屬性中。
function Fruit() {
}
Fruit.prototype.name = "apple";
Fruit.prototype.number = 5;
Fruit.prototype.showName = function() {
alert(this.name);
};
var fruit1 = new Fruit();
var fruit2 = new Fruit();
但是,這樣同樣存在一些缺點。首先,建構函式中沒有參數,給初始化帶來一些麻煩,其次,當一個屬性指向的是一個對象而非方法時,該對象會被所有的執行個體所共用,任何一點改動都會影響到其他對象引用的使用。
5.4 混合使用Factory 方法和Prototype
這個概念很簡單:使用建構函式定義所有除方法外的屬性,使用 prototype 定義對象的方法。這樣每個方法只會被建立一次,每個對象都能擁有自己對象執行個體的屬性。
function Fruit(name, number) {
this.name = name;
this.number = number;
this.owner = new Array("Jerry", "Terry");
}
Fruit.prototype.showName = function() {
alert(this.name);
};
var Fruit1 = new Fruit("apple", 5);
var Fruit2 = new Fruit("pear", 3);
5.5 動態 prototype
簡單來說,這種方法就是使用了一個標識符來判斷 prototype 是否已經被指向某個方法,從而保證這些方法只會被建立並指向一次。
5.6 混合Factory 方法
這種方法和經典的Factory 方法及建構函式方法在對象方法記憶體管理上存在同樣的問題,一般不建議使用該方法,除了某些特殊情況(XML in JavaScript中有這樣的例子)。
6 修改對象
使用prototype對象可以對對象進行修改。除了使用者自訂的對象外,ECMAScript原始對象也有prototype屬性。直接使用 prototype可以給對象建立新的方法。
Number.prototype.toHexString = function() {
return this.toString(16);
};
var iNum = 10;
alert(iNum.toHexString()); //輸出A
另外,使用prototype可以輕鬆修改已有的方法,讓方法名指向新的方法。需要注意的是,指向新的方法後,原有的方法不再被任何對象使用,將會被記憶體回收行程銷毀,使得原有方法不再存在。比較安全的解決辦法是,建立一個新的引用來儲存原有的方法,然後再將原方法覆蓋。
比較特殊的是,ECMAScript中建立對象,在對象引用被建立後,可以給對象加入新的方法,並且可以立即在對象的引用中使用。這是ECMAScript的一個特性,但不推薦這樣使用,以免帶來不必要的麻煩,例如閱讀理解、文檔資料等。