編寫類一般有如下幾種方法
1. 工廠函數方式(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>
但以上方法有個問題,就是每次調用函數createCar()時,都會創建新函數showColor(),這意味著每個對象都有自己的showColor()版本,但事實上,每個對象都共享了同一個函數。
以下方案可以解決這個問題:
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"
以上黃色的部分為修改了的代碼,這樣就解決了重復創建函數對象的問題,但這個函數看起來不像是對象的方法,所以這個應該說也不是完美的解決方案
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();
以上方式有兩個缺陷:1. 不能通過構造函數來給對象傳遞參數初始化屬性,必須在創建以后才能改;2. 當屬性指向的是對象而不是函數時。??聪旅娴睦樱?
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"
呵呵,所有非函數屬性都在構造函數中創建,而函數則綁定到原型上,這個就是很完美的解決方案了
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"
呵呵,如何,這樣就只會創建一次方法而方法又在類里面了,視覺上也要好看點
顯然,最后兩種方法都是推薦使用的
最后說明下,以上源代碼均來自Nicholas C. Zakas的《Professional JavaScript for Web Developers》