javascript中類的定義及其方式(《javascript高級程序設(shè)計(jì)》學(xué)習(xí)筆記)
關(guān)于javascript中類的繼承可以參考阮一峰的Blog《Javascript繼承機(jī)制的設(shè)計(jì)思想》,說的很透。
一、在javascript中實(shí)例化遇到的問題:
下面用《javascript高級程序設(shè)計(jì)》中的例子來做說明,假如現(xiàn)在定義了一個(gè)car的對象,它是Object類的實(shí)例。像下面這樣的:
var oCar=new Object();
oCar.color = "red";
oCar.doors = 4;
oCar.mpg = 23;
oCar.showColor = function () {
alert(this.color);
};
現(xiàn)在又需要這樣的一個(gè)實(shí)例,你可能會(huì)像這樣來定義:
var oCar2 = new Object();
oCar2.color = "blue";
oCar2.doors = 5;
oCar2.mpg = 25;
oCar2.showColor = function () {
alert(this.color);
};
這樣遇到的問題是每個(gè)對象都需要重新定義一次他的字段和方法。很麻煩。
二、類的定義--工廠方式實(shí)現(xiàn):
對上面的例子進(jìn)行一個(gè)包裝,利用函數(shù)的返回值來做文章:
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è)對象的時(shí)候不再需要那么多的行數(shù)。因?yàn)槊總€(gè)屬性(color,doors,mpg)的值都是固定的,還需要再次進(jìn)行改造,利用參數(shù)傳遞來實(shí)現(xiàn):
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)了對象了。實(shí)現(xiàn)也很簡單,調(diào)用也很方便。但是有兩個(gè)不是很好的地方:
1、從語義上看,在創(chuàng)建對象時(shí)沒有使用new運(yùn)算符,似乎不是那么正規(guī)(通常創(chuàng)建一個(gè)對象都用一個(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ù):
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ù)看起來不像是對象的方法。
三、類的定義--構(gòu)造函數(shù)方式實(shí)現(xiàn):
function Car(sColor, iDoors, iMpg) {
//通過構(gòu)造函數(shù)的形式,會(huì)為每個(gè)對象生成獨(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è)問題,但是這么做的話,在語義上沒有意義。
四、類的定義--原型方式實(shí)現(xiàn):
利用對象的prototype屬性,把它看成是創(chuàng)建新對象所依賴的原型。用空構(gòu)造函數(shù)來設(shè)置類名。然后所有的屬性和方法都被直接賦予prototype屬性。
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í),對其中一個(gè)實(shí)例的屬性的更改會(huì)影響到另外一個(gè)實(shí)例的屬性。
測試代碼:
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)方式是使用最廣泛的方式。
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)完成的)。這種類的定義方式使用也很多。
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)
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)建的對象被傳回變量var。雖然看起來有了new運(yùn)算符了,比工廠方式有了一些進(jìn)步,但是這種實(shí)現(xiàn)方式也是會(huì)出現(xiàn)重復(fù)創(chuàng)建方法的問題。因此也不推薦使用這種方式來定義類。
- JavaScript高級程序設(shè)計(jì) DOM學(xué)習(xí)筆記
- JavaScript高級程序設(shè)計(jì) XML、Ajax 學(xué)習(xí)筆記
- JavaScript高級程序設(shè)計(jì) 事件學(xué)習(xí)筆記
- JavaScript高級程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記 概述
- JavaScript高級程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記2 js基礎(chǔ)語法
- JavaScript高級程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記3 js簡單數(shù)據(jù)類型
- JavaScript高級程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記4 js運(yùn)算符和操作符
- JavaScript高級程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記5 js語句
- JavaScript高級程序設(shè)計(jì)(第三版)學(xué)習(xí)筆記1~5章
相關(guān)文章
JavaScript定義類或函數(shù)的幾種方式小結(jié)
js中不論是定義類或者函數(shù),很多朋友想將代碼寫的更專業(yè),更方便擴(kuò)展等,那么就可以參考這篇文章了,最好是總結(jié),建議大家收藏下。2011-01-01編寫可維護(hù)面向?qū)ο蟮腏avaScript代碼[翻譯]
編寫可維護(hù)面向?qū)ο蟮腏avaScript代碼[翻譯],學(xué)習(xí)js面向?qū)ο缶帉懙呐笥芽梢詤⒖枷隆?/div> 2011-02-02javascript 設(shè)計(jì)模式之單體模式 面向?qū)ο髮W(xué)習(xí)基礎(chǔ)
單體是在腳本加載時(shí)創(chuàng)建的,能將一系列有關(guān)聯(lián)的變量和方法組織為一個(gè)邏輯單元,邏輯單元里面的內(nèi)容通過單一的變量進(jìn)行訪問,也是筆記基礎(chǔ)與常用的面向?qū)ο蟮亩x方法。2010-04-04學(xué)習(xí)JS面向?qū)ο蟪晒?借國慶發(fā)布個(gè)最新作品與大家交流
學(xué)習(xí)JS面向?qū)ο蟪晒?,借國慶發(fā)布個(gè)最新作品與大家交流,大家可以看下。2009-10-10javascript 面向?qū)ο缶幊袒A(chǔ) 多態(tài)
javascript 面向?qū)ο缶幊袒A(chǔ) 多態(tài) 的實(shí)現(xiàn)方法說明,大家可以看下下面的代碼。2009-08-08最新評論