javascript中類的定義及其方式(《javascript高級(jí)程序設(shè)計(jì)》學(xué)習(xí)筆記)
更新時(shí)間:2011年07月04日 23:15:02 作者:
javascript也是一種面向?qū)ο蟮木幊陶Z(yǔ)言。但是javascript中的類相關(guān)的東西(類的定義,原型鏈,繼承等)卻不是很好理解,特別是繼承。
關(guān)于javascript中類的繼承可以參考阮一峰的Blog《Javascript繼承機(jī)制的設(shè)計(jì)思想》,說的很透。
一、在javascript中實(shí)例化遇到的問題:
下面用《javascript高級(jí)程序設(shè)計(jì)》中的例子來做說明,假如現(xiàn)在定義了一個(gè)car的對(duì)象,它是Object類的實(shí)例。像下面這樣的:
復(fù)制代碼 代碼如下:
var oCar=new Object();
oCar.color = "red";
oCar.doors = 4;
oCar.mpg = 23;
oCar.showColor = function () {
alert(this.color);
};
現(xiàn)在又需要這樣的一個(gè)實(shí)例,你可能會(huì)像這樣來定義:
復(fù)制代碼 代碼如下:
var oCar2 = new Object();
oCar2.color = "blue";
oCar2.doors = 5;
oCar2.mpg = 25;
oCar2.showColor = function () {
alert(this.color);
};
這樣遇到的問題是每個(gè)對(duì)象都需要重新定義一次他的字段和方法。很麻煩。
二、類的定義--工廠方式實(shí)現(xiàn):
對(duì)上面的例子進(jìn)行一個(gè)包裝,利用函數(shù)的返回值來做文章:
復(fù)制代碼 代碼如下:
function createCar() {
var oTempCar = new Object();
oTempCar.color = "red";
oTempCar.doors = 4;
oTempCar.mpg = 23;
oTempCar.showColor = function () {
alert(this.color);
};
return oTempCar;
}
調(diào)用方式:
var oCar1 = createCar();
var oCar2 = createCar();
這種方式被稱之為工廠方式。工廠方式看起來是省事多了。起碼創(chuàng)建一個(gè)對(duì)象的時(shí)候不再需要那么多的行數(shù)。因?yàn)槊總€(gè)屬性(color,doors,mpg)的值都是固定的,還需要再次進(jìn)行改造,利用參數(shù)傳遞來實(shí)現(xiàn):
復(fù)制代碼 代碼如下:
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("red", 4, 23);
oCar1.showColor();
oCar2.showColor();
這樣做看似的確可以實(shí)現(xiàn)了對(duì)象了。實(shí)現(xiàn)也很簡(jiǎn)單,調(diào)用也很方便。但是有兩個(gè)不是很好的地方:
1、從語(yǔ)義上看,在創(chuàng)建對(duì)象時(shí)沒有使用new運(yùn)算符,似乎不是那么正規(guī)(通常創(chuàng)建一個(gè)對(duì)象都用一個(gè)new運(yùn)算符來實(shí)現(xiàn))。
2、不符合面向?qū)ο蟮奶卣?-封裝。在這個(gè)例子中,oCar1和oCar2都有自己的showColor方法,并且他們的showColor都是自己的實(shí)現(xiàn)。但是事實(shí)是他們共享的是同一個(gè)函數(shù)。
也是有辦法解決這個(gè)共享函數(shù)的問題,利用函數(shù)指針來解決。在createCar函數(shù)之外再創(chuàng)建一個(gè)showColor函數(shù),而oTempCar的showColor方法指向這個(gè)showColor函數(shù):
復(fù)制代碼 代碼如下:
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("red", 4, 23);
oCar1.showColor();
oCar2.showColor();
雖然這樣解決了重復(fù)創(chuàng)建函數(shù)的問題,但這樣的話,就使showColor函數(shù)看起來不像是對(duì)象的方法。
三、類的定義--構(gòu)造函數(shù)方式實(shí)現(xiàn):
復(fù)制代碼 代碼如下:
function Car(sColor, iDoors, iMpg) {
//通過構(gòu)造函數(shù)的形式,會(huì)為每個(gè)對(duì)象生成獨(dú)立的屬性和函數(shù)
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("red", 4, 23);
oCar1.showColor();
oCar2.showColor();
在Car類中,this指針代表了Car的一個(gè)實(shí)例,因此不需要返回值。雖然構(gòu)造函數(shù)方式實(shí)現(xiàn)了類的定義,但是和工廠方式一樣,他也是為每個(gè)實(shí)例創(chuàng)建一個(gè)單獨(dú)的方法。雖然可以像工廠函數(shù)一樣在函數(shù)之外再創(chuàng)建一個(gè)函數(shù)利用指針來解決這個(gè)問題,但是這么做的話,在語(yǔ)義上沒有意義。
四、類的定義--原型方式實(shí)現(xiàn):
利用對(duì)象的prototype屬性,把它看成是創(chuàng)建新對(duì)象所依賴的原型。用空構(gòu)造函數(shù)來設(shè)置類名。然后所有的屬性和方法都被直接賦予prototype屬性。
復(fù)制代碼 代碼如下:
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();
alert(oCar1 instanceof Car);//output true這里存在兩個(gè)問題:
1、構(gòu)造函數(shù)沒有參數(shù)。使用原型時(shí),不能通過給函數(shù)參數(shù)傳遞參數(shù)來初始化屬性值。
2、在有多個(gè)實(shí)例時(shí),對(duì)其中一個(gè)實(shí)例的屬性的更改會(huì)影響到另外一個(gè)實(shí)例的屬性。
測(cè)試代碼:
復(fù)制代碼 代碼如下:
var oCar1 = new Car();
oCar1.color = "Green";
var oCar2 = new Car();
oCar2.color = "Black";
alert(oCar1.color); //output Green
alert(oCar2.color); //output Black
alert(oCar1.color); //output Black
當(dāng)然了,也會(huì)有辦法解決這個(gè)問題的。那就是混合的構(gòu)造函數(shù)/原型方式
五、類的實(shí)現(xiàn)--混合的構(gòu)造函數(shù)/原型方式實(shí)現(xiàn)
這種實(shí)現(xiàn)方式是將每個(gè)類的實(shí)例中共享的屬性或者方法妨到原型鏈中實(shí)現(xiàn),而將不需要共享實(shí)現(xiàn)的屬性和方法放在構(gòu)造函數(shù)中實(shí)現(xiàn)。這中類的實(shí)現(xiàn)方式是使用最廣泛的方式。
復(fù)制代碼 代碼如下:
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, 24);
oCar1.drivers.push("Matt");
alert(oCar1.drivers);
alert(oCar2.drivers);六、類的定義--動(dòng)態(tài)原型方式實(shí)現(xiàn)
這種方式和混合的構(gòu)造函數(shù)/原型方式相比,提供了一種友好的編程風(fēng)格(在混合的構(gòu)造函數(shù)/原型方式中,showColor方法的定義是在方法體外實(shí)現(xiàn)的,而不是在構(gòu)造函數(shù)的方法體內(nèi)完成的)。這種類的定義方式使用也很多。
復(fù)制代碼 代碼如下:
function Car(sColor, iDoors, iMpg) {
this.color = sColor;
this.doors = iDoors;
this.mpg = iMpg;
this.divers = new Array("Mike", "Sue");
if (typeof Car._initialized == "undefined") {
Car.prototype.showColor = function () {
alert(this.color);
};
Car._initialized = true;
}
七、類的定義--混合工廠方式實(shí)現(xiàn)
復(fù)制代碼 代碼如下:
function Car() {
var oTempCar = new Object();
oTempCar.color = "red";
oTempCar.doors = 4;
oTempCar.mpg = 23;
oTempCar.showColor = function () {
alert(this.color);
};
return oTempCar;
}
var car = new Car();
car.showColor();
這種方式和工廠方式看起來差不多。由于在Car()構(gòu)造函數(shù)內(nèi)部調(diào)用了new運(yùn)算符,所以將忽略掉位于構(gòu)造函數(shù)之外的new運(yùn)算符。在構(gòu)造函數(shù)內(nèi)部創(chuàng)建的對(duì)象被傳回變量var。雖然看起來有了new運(yùn)算符了,比工廠方式有了一些進(jìn)步,但是這種實(shí)現(xiàn)方式也是會(huì)出現(xiàn)重復(fù)創(chuàng)建方法的問題。因此也不推薦使用這種方式來定義類。
您可能感興趣的文章:
- JavaScript高級(jí)程序設(shè)計(jì) DOM學(xué)習(xí)筆記
- JavaScript高級(jí)程序設(shè)計(jì) XML、Ajax 學(xué)習(xí)筆記
- JavaScript高級(jí)程序設(shè)計(jì) 事件學(xué)習(xí)筆記
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記 概述
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記2 js基礎(chǔ)語(yǔ)法
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記3 js簡(jiǎn)單數(shù)據(jù)類型
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記4 js運(yùn)算符和操作符
- JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記5 js語(yǔ)句
- JavaScript高級(jí)程序設(shè)計(jì)(第三版)學(xué)習(xí)筆記1~5章
相關(guān)文章
JavaScript isPrototypeOf和hasOwnProperty使用區(qū)別
JavaScript isPrototypeOf和hasOwnProperty的使用技巧,需要的朋友的朋友可以參考下。2010-03-03
最簡(jiǎn)單的javascript對(duì)象實(shí)例代碼
非常簡(jiǎn)單的js面向?qū)ο髮?shí)例代碼,主要是利用了this,對(duì)于js面向?qū)ο蟮膶W(xué)習(xí)資料,可以查看腳本之家以前的文章。2009-12-12

