JavaScript 物件設計模式
一、定義類和物件:
1、工廠方式
原始的方式:建立物件,然後給它設定幾個屬性
函式建立物件方法:解決原始的方式每建立一個例項都需要建立一個原始的方式
函式建立物件方法傳遞引數:讓上面的函式建立物件方法可以傳遞屬性
函式建立物件方法傳遞函式方法:工廠函式外定義物件的方法,然後通過屬性指向該方法
function showColor() {
alert(this.color);
}
function createCar(sColor,iDoors,iMpg) {
var oTempCar = new Object;
oTempCar.color = sColor;
oTempCar.doors = iDoors;
oTempCar.mpg = iMpg;
oTempCar.showColor = showColor;
return oTempCar;
}
var oCar1 = createCar("red",4,23);
var oCar2 = createCar("blue",3,25);
oCar1.showColor(); //輸出 "red"
oCar2.showColor(); //輸出 "blue"
2、建構函式方式
第一步選擇類名,即建構函式的名字。根據慣例,這個名字的首字母大寫,以使它與首字母通常是小寫的變數名分開。除了這點不同,建構函式看起來很像工廠
與工廠方式區別:建構函式內沒有建立物件,而是使用 this 關鍵字。使用 new 運算子建構函式時,在執行第一行程式碼前先建立一個物件,只有用 this 才能訪問該物件。然後可以直接賦予 this 屬性,預設情況下是建構函式的返回值(不必明確使用 return 運算子)。
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.showColor = function() {
alert(this.color) ;
};
}
var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);
3、原型方式
利用了物件的 prototype 屬性,可以把它看成建立新物件所依賴的原型
原型方式的問題:
必須在物件建立後才能改變屬性的預設值
屬性指向的是物件,而不是函式時。函式共享不會造成問題,但物件卻很少被多個例項共享(物件改變大家都改變)
混合的建構函式/原型方式(解決原型方式問題)
動態原型方法
混合工廠方式
二、常用的方法
1、混合的建構函式/原型方式
用建構函式定義物件的所有非函式屬性,用原型方式定義物件的函式屬性(方法)。結果是,所有函式都只建立一次,而每個物件都具有自己的物件屬性例項。
function Car(sColor,iDoors,iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.drivers = new Array("Mike","John");
}
Car.prototype.showColor = function() {
alert(this.color);
};
var oCar1 = new Car("red",4,23);
var oCar2 = new Car("blue",3,25);
oCar1.drivers.push("Bill");
alert(oCar1.drivers); //輸出 "Mike,John,Bill"
alert(oCar2.drivers); //輸出 "Mike,John"
現在就更像建立一般物件了。所有的非函式屬性都在建構函式中建立,意味著又能夠用建構函式的引數賦予屬性預設值了。因為只建立 showColor() 函式的一個例項,所以沒有記憶體浪費。此外,給 oCar1 的 drivers 陣列新增 “Bill” 值,不會影響到 oCar2 的陣列,所以輸出這些陣列的值時,oCar1.drivers 顯示的是 “Mike,John,Bill”,而 oCar2.drivers 顯示的是 “Mike,John”。因為使用了原型方式,所以仍然能利用 instanceof 運算子來判斷物件的型別。
這種方式是 ECMAScript 採用的主要方式,它具有其他方式的特性,卻沒有他們的副作用。不過,有些開發者仍覺得這種方法不夠完美。