編寫類一般有如下幾種方法
1. 工廠函數(shù)方式(factory function)
<script type="text/javascript">
function createCar(sColor, iDoors, iMpg) {
var oTempCar = new Object;
oTempCar.color = sColor;
oTempCar.doors = iDoors;
oTempCar.mpg = iMpg;
oTempCar.showColor = function () {
alert(this.color);
};
return oTempCar;
}
var oCar1 = createCar("red", 4, 23);
var oCar2 = createCar("blue", 3, 25);
oCar1.showColor(); //outputs "red"
oCar2.showColor(); //outputs "blue"
</script>
但以上方法有個問題,就是每次調(diào)用函數(shù)createCar()時,都會創(chuàng)建新函數(shù)showColor(),這意味著每個對象都有自己的showColor()版本,但事實(shí)上,每個對象都共享了同一個函數(shù)。
以下方案可以解決這個問題:
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(); //outputs "red";
oCar2.showColor(); //outputs "blue"
以上黃色的部分為修改了的代碼,這樣就解決了重復(fù)創(chuàng)建函數(shù)對象的問題,但這個函數(shù)看起來不像是對象的方法,所以這個應(yīng)該說也不是完美的解決方案
2. 構(gòu)造函數(shù)方式
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"
這種方式應(yīng)該是現(xiàn)在用的最多的方式了,但和工廠方法有同樣的問題,就是會重復(fù)生成函數(shù) ,當(dāng)然,也可以如工廠函數(shù)方法一般將函數(shù)提到外面去再引用,這同樣不完美,呵呵
3. 原型構(gòu)造方法
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();
以上方式有兩個缺陷:1. 不能通過構(gòu)造函數(shù)來給對象傳遞參數(shù)初始化屬性,必須在創(chuàng)建以后才能改;2. 當(dāng)屬性指向的是對象而不是函數(shù)時。??聪旅娴睦樱?
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. 混合構(gòu)造函數(shù)/原型方式
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"
呵呵,所有非函數(shù)屬性都在構(gòu)造函數(shù)中創(chuàng)建,而函數(shù)則綁定到原型上,這個就是很完美的解決方案了
5. 動態(tài)原型方法
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"
呵呵,如何,這樣就只會創(chuàng)建一次方法而方法又在類里面了,視覺上也要好看點(diǎn)
顯然,最后兩種方法都是推薦使用的
最后說明下,以上源代碼均來自Nicholas C. Zakas的《Professional JavaScript for Web Developers》