編寫類一般有如下幾種方法
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>
但以上方法有個(gè)問(wèn)題,就是每次調(diào)用函數(shù)createCar()時(shí),都會(huì)創(chuàng)建新函數(shù)showColor(),這意味著每個(gè)對(duì)象都有自己的showColor()版本,但事實(shí)上,每個(gè)對(duì)象都共享了同一個(gè)函數(shù)。
以下方案可以解決這個(gè)問(wèn)題:
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ù)對(duì)象的問(wèn)題,但這個(gè)函數(shù)看起來(lái)不像是對(duì)象的方法,所以這個(gè)應(yīng)該說(shuō)也不是完美的解決方案
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)在用的最多的方式了,但和工廠方法有同樣的問(wèn)題,就是會(huì)重復(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();
以上方式有兩個(gè)缺陷:1. 不能通過(guò)構(gòu)造函數(shù)來(lái)給對(duì)象傳遞參數(shù)初始化屬性,必須在創(chuàng)建以后才能改;2. 當(dāng)屬性指向的是對(duì)象而不是函數(shù)時(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"
呵呵,是不是覺得很惡?看來(lái)這種方式顯然也是不對(duì)的
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ù)則綁定到原型上,這個(gè)就是很完美的解決方案了
5. 動(dòng)態(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"
呵呵,如何,這樣就只會(huì)創(chuàng)建一次方法而方法又在類里面了,視覺上也要好看點(diǎn)
顯然,最后兩種方法都是推薦使用的
最后說(shuō)明下,以上源代碼均來(lái)自Nicholas C. Zakas的《Professional JavaScript for Web Developers》