javascript進階程式設計---模式設計
1.工廠方式建立對象car
var oCar = new Object;oCar.color = "red";oCar.doors = 4;oCar.mpg = 23;oCar.showColor = function(){ alert(this.corlor);};
建立多個car
function createCar(color, doors, mpg) { var tempcar = new Object; tempcar.color = color; tempcar.doors = doors; tempcar.mpg = mpg; tempcar.showColor = function () { alert(this.color) }; return tempcar;}var car1 = createCar("red", 4, 23);var car2 = createCar("blue", 3, 25);car1.showColor(); //outputs "red"car2.showColor(); //outputs "blue"
這個例子中,每次調用函數createCar(),都要建立新函數showColor(),意味著每個對象都有自己的showColor()版本,事實上,每個對象都共用了同一個函數。
有些開發人員在工廠函數外定義對象的方法,然後通過屬性指向該方法,從而避開這個問題。
function showColor(){ alert(this.color);}function createCar(color, doors, mpg) { var tempcar = new Object; tempcar.color = color; tempcar.doors = doors; tempcar.mpg = mpg; tempcar.showColor = showColor; return tempcar;}var car1 = createCar("red", 4, 23);var car2 = createCar("blue", 3, 25);car1.showColor(); //outputs "red"car2.showColor(); //outputs "blue"
從功能上講,這樣解決了重複建立函數對象的問題,但該函數看起來不像對象的方法。所有這些問題引發了開發人員定義的建構函式的出現。
2.建構函式方法
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);oCar1.showColor(); //outputs "red"oCar2.showColor(); //outputs "blue"
就像工廠函數,建構函式會重複產生函數,為每個對象都建立獨立的函數版本。不過,也可以用外部函數重寫建構函式,同樣,這麼做語義上無任何意義。
3.原型方式
function Car(){}Car.prototype.color = "red";Car.prototype.doors= 4;Car.prototype.mpg= 23;Car.prototype.showColor = function(){ alert(this.color);}var oCar1 = new Car();var oCar2 = new Car();它解決了前面兩種方式存在的兩個問題。但並不盡人意。首先,這個建構函式沒有參數。使用原型方式時,不能通過建構函式傳遞參數初始化屬性的值,這點很令人計厭,但還沒完,真正的問題出現在屬性指向的是對象,而不是函數時。考慮下面的例子:
function Car(){}Car.prototype.color = "red";Car.prototype.doors= 4;Car.prototype.mpg= 23;Car.prototype.drivers = new Array("Mike","Sue");Car.prototype.showColor = function(){ alert(this.color);}var oCar1 = new Car();var oCar2 = new Car();oCar1.drivers.push("Matt");alert(oCar1.drivers); //outputs "Mike,Sue,Matt"alert(oCar2.drivers); //outputs "Mike,Sue,Matt"4.混合的建構函式/原型方式
function Car(sColor, iDoors, iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array("Mike", "Sue");}Car.prototype.showColor = function () { alert(this.color);};var oCar1 = new Car("red", 4, 23);var oCar2 = new Car("blue", 3, 25);oCar1.drivers.push("Matt");alert(oCar1.drivers); //outputs "Mike,Sue,Matt"alert(oCar2.drivers); //outputs "Mike,Sue"現在就更像建立一般對象了。所有的非函數屬性都有建構函式中建立,意味著又可用建構函式的參數賦予屬性預設值了。因為只建立showColor()函數的一個執行個體,所以沒有記憶體浪費。
5.動態原型方法
function Car(sColor, iDoors, iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array("Mike", "Sue"); if (typeof Car._initialized == "undefined") { Car.prototype.showColor = function () { alert(this.color); }; Car._initialized = true; }}var oCar1 = new Car("red", 4, 23);var oCar2 = new Car("blue", 3, 25);oCar1.drivers.push("Matt");alert(oCar1.drivers); //outputs "Mike,Sue,Matt"alert(oCar2.drivers); //outputs "Mike,Sue"動態原型方法的基本想法與混合的建構函式/原型方式相同,即在建構函式內定義非函數屬性,而函數屬性則利用原型屬性定義。唯一的區別是賦予對象方法的位置。
6.混合工廠方式這種方式通常是在不能應用前一種方式時的變通方法。它的目的是建立假建構函式,只返回另一種對象的新執行個體。
function Car() { var tempcar = new Object; tempcar.color = "red"; tempcar.doors = 4; tempcar.mpg = 23; tempcar.showColor = function () { alert(this.color) }; return tempcar;}與經典方式不同,這種方式使用new運算子,使它看起來像真正的建構函式。
7.採用哪種方式 如前所述,目前使用最廣泛的是混合的建構函式/原型方式。些外,動態原型方法也很流行,在功能上與前者等價,可以採用這兩種方式中的任何一種。