天天看點

javascript進階程式設計---模式設計

  1. 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"
           

從功能上講,這樣解決了重複建立函數對象的問題,但該函數看起來不像對象的方法。所有這些問題引發了開發者定義的構造函數的出現。

  1. 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"
           

就像工廠函數,構造函數會重複生成函數,為每個對象都建立獨立的函數版本。不過,也可以用外部函數重寫構造函數,同樣,這麼做語義上無任何意義。

  1. 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"
           

  1. 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()函數的一個執行個體,是以沒有記憶體浪費。

  1. 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"
           

動态原型方法的基本想法與混合的構造函數 /原型方式相同,即在構造函數内定義非函數屬性,而函數屬性則利用原型屬性定義。唯一的差別是賦予對象方法的位置。

  1. 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運算符,使它看起來像真正的構造函數。

  1. 7.采用哪種方式

   如前所述,目前使用最廣泛的是混合的構造函數/原型方式。些外,動态原型方法也很流行,在功能上與前者等價,可以采用這兩種方式中的任何一種。

繼續閱讀