|
??? 作者:Flyingis
5? 自定義類和對(duì)象
5.1? 工廠方法
??? 在ECMAScript中創(chuàng)建工廠方法,返回一個(gè)特定類型的對(duì)象,以此實(shí)現(xiàn)代碼的簡(jiǎn)潔適用。
 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()中可以加入形參來傳入?yún)?shù)的值。隨著ECMAScript不斷被規(guī)范化,這種創(chuàng)建對(duì)象的方法已不再流行,一部分原因是語法上的,一部分原因是功能上的,如每個(gè)對(duì)象的實(shí)例都擁有屬于自己的showName方法,給內(nèi)存管理帶來一定的開銷。
5.2? 構(gòu)造函數(shù)
??? 選擇一個(gè)類名,第一個(gè)字母大寫,該類名即是構(gòu)造函數(shù)的名稱。創(chuàng)建一個(gè)構(gòu)造函數(shù)和工廠方法比較類似,不同的是需要使用關(guān)鍵字new來創(chuàng)建對(duì)象的引用。使用構(gòu)造函數(shù)的方式來創(chuàng)建對(duì)象和使用工廠方法有著相同的弊端。
 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屬性可以用來創(chuàng)建新的對(duì)象,首先需要一個(gè)空的構(gòu)造函數(shù)建立類的名稱,然后所有的屬性和方法都直接分配到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(); ??? 但是,這樣同樣存在一些缺點(diǎn)。首先,構(gòu)造函數(shù)中沒有參數(shù),給初始化帶來一些麻煩,其次,當(dāng)一個(gè)屬性指向的是一個(gè)對(duì)象而非方法時(shí),該對(duì)象會(huì)被所有的實(shí)例所共享,任何一點(diǎn)改動(dòng)都會(huì)影響到其他對(duì)象引用的使用。
5.4? 混合使用工廠方法和Prototype
這個(gè)概念很簡(jiǎn)單:使用構(gòu)造函數(shù)定義所有除方法外的屬性,使用 prototype 定義對(duì)象的方法。這樣每個(gè)方法只會(huì)被創(chuàng)建一次,每個(gè)對(duì)象都能擁有自己對(duì)象實(shí)例的屬性。
 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? 動(dòng)態(tài) prototype
??? 簡(jiǎn)單來說,這種方法就是使用了一個(gè)標(biāo)識(shí)符來判斷 prototype 是否已經(jīng)被指向某個(gè)方法,從而保證這些方法只會(huì)被創(chuàng)建并指向一次。
5.6? 混合工廠方法
??? 這種方法和經(jīng)典的工廠方法及構(gòu)造函數(shù)方法在對(duì)象方法內(nèi)存管理上存在同樣的問題,一般不建議使用該方法,除了某些特殊情況(XML in JavaScript中有這樣的例子)。
6? 修改對(duì)象
??? 使用prototype對(duì)象可以對(duì)對(duì)象進(jìn)行修改。除了用戶自定義的對(duì)象外,ECMAScript原始對(duì)象也有prototype屬性。直接使用 prototype可以給對(duì)象創(chuàng)建新的方法。
 Number.prototype.toHexString?=?function()? {
??return?this.toString(16);
};
var?iNum?=?10;
alert(iNum.toHexString());??//輸出A ??? 另外,使用prototype可以輕松修改已有的方法,讓方法名指向新的方法。需要注意的是,指向新的方法后,原有的方法不再被任何對(duì)象使用,將會(huì)被垃圾回收器銷毀,使得原有方法不再存在。比較安全的解決辦法是,建立一個(gè)新的引用來保存原有的方法,然后再將原方法覆蓋。
??? 比較特殊的是,ECMAScript中創(chuàng)建對(duì)象,在對(duì)象引用被創(chuàng)建后,可以給對(duì)象加入新的方法,并且可以立即在對(duì)象的引用中使用。這是ECMAScript的一個(gè)特性,但不推薦這樣使用,以免帶來不必要的麻煩,例如閱讀理解、文檔資料等。
|