JS中類或對象的定義說明
更新時間:2014年03月10日 09:35:31 作者:
本篇文章主要是對JS中類或對象的定義進行了說明介紹,需要的朋友可以過來參考下,希望對大家有所幫助
我們知道,JS是面向對象的。談到面向對象,就不可避免的要涉及類的概念。一般像c#,java這些強類型語言都有固定的定義類的語法。而JS的不同之處在于它能使用各種方法實現(xiàn)自己的類和對象。一般的實現(xiàn)有以下幾種方式:
1.工廠方式
工廠方式是指創(chuàng)建一個返回特定對象類型的工廠函數(shù),示例代碼如下:
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();
oCar2.showColor();
這種方式每次調用它的工廠函數(shù),都會創(chuàng)建一個新對象??蓡栴}在于每次生成一個新對象,都要創(chuàng)建新函數(shù)showColor,這使得每個對象都有自己的showColor版本,而事實上,所有的對象都共享同一個函數(shù).為解決這個問題,開發(fā)者在工廠函數(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();
oCar2.showColor();
這樣就不需要為每一個對象都創(chuàng)建自己的showColor函數(shù),而只是創(chuàng)建指向這個函數(shù)的指針.這從功能上解決了問題,但是該函數(shù)卻不像對象的方法。于是,引出了構造函數(shù)的方式。
2.構造函數(shù)方式
構造函數(shù)與工廠函數(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);
在構造函數(shù)中,內(nèi)部無創(chuàng)建對象,而是使用this關鍵字。使用new運算符調用構造函數(shù)時,在執(zhí)行第一行代碼之前先創(chuàng)建一個對象,只有用this才能訪問這個對象。但是這會遇到什么問題呢,很顯然,它的每個對象也都會創(chuàng)建自己的showColor函數(shù)版本。為解決這個問題,引出了以下的原型方式.
3.原型方式
該方式利用了對象的prototype屬性,可把它看成創(chuàng)建新對象所依賴的原型。這里,用空構造函數(shù)來設置類名。然后把所有的方法和屬性都直接賦予prototype屬性。如下:
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);
}
原型方式只能直接賦值,而不能通過給構造函數(shù)傳遞參數(shù)初始化屬性的值。在用這種方式時,會遇到兩個問題,不知道大家注意到?jīng)]有。第一問題是采用這種方式必須創(chuàng)建每個對象后才能改變屬性的默認值。而不能在創(chuàng)建每個對象時都會直接有自己所需要的屬性值。這點很討厭。第二個問題在于屬性所指的是對象的時候。函數(shù)共享不會出現(xiàn)任何問題,但是對象共享卻會出現(xiàn)問題。因為每個實例一般都要實現(xiàn)自己的對象。
如下面:
var oCar1=new Car();
var oCar2=new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers);//輸出 "Mike,Sue,Matt"
alert(oCar2.drivers);//輸出"Mike,Sue,Matt"
因此drivers屬性只是指向對象的指針,所以所有的實例事實上共享同一個對象。由于出現(xiàn)這這些問題,我們引出了下面的聯(lián)合使用構造函數(shù)和原型方式。
4.混合的構造函數(shù)/原型方式
這種方式的思想是用構造函數(shù)定義對象的所有非函數(shù)屬性(包括普通屬性和指向對象的屬性),用原型方式定義對象的函數(shù)屬性(方法)。結果使得所有的函數(shù)都只被創(chuàng)建一次,而每個對象都有自己的對象屬性實例。示例代碼如下:
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);//輸出 "Mike,Sue,Matt"
alert(oCar2.drivers);//輸出 "Mike,Sue"
由實例代碼可知,這種方式同時解決了上一種方式的兩個問題。不過,采用這種方式,仍有些開發(fā)者覺得不夠完美。
5.動態(tài)原型方式
我們可知,大多數(shù)面向對象語言都對屬性和方法進行了視覺上的封裝。而上述方式的showColor方法卻定義在了類的外面。因此,他們設計了動態(tài)原型方法。這種方式的基本思想和混合的構造函數(shù)/原型方式相同,唯一不同之處在于對象方法的位置。如下所示:
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;
}
這種方式Car.prototype.showColor只被創(chuàng)建一次。這樣依賴,這段代碼更像其他語言中的類定義了。
6.混合工廠方式
這種方式通常是不能應該前一種方式的變通方法。它的目的是創(chuàng)建假構造函數(shù),只返回另一種對象的新實例。
function createCar()
{
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()構造函數(shù)內(nèi)部調用了new運算符,所以自動忽略第二個new運算符。在構造函數(shù)內(nèi)部創(chuàng)建的對象被傳遞回變量var。這種方式在對象方法的內(nèi)部管理方面與經(jīng)典方式有著相同的問題。所以強烈建議:除非萬不得已,還是避免使用這種方式。
1.工廠方式
工廠方式是指創(chuàng)建一個返回特定對象類型的工廠函數(shù),示例代碼如下:
復制代碼 代碼如下:
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();
oCar2.showColor();
這種方式每次調用它的工廠函數(shù),都會創(chuàng)建一個新對象??蓡栴}在于每次生成一個新對象,都要創(chuàng)建新函數(shù)showColor,這使得每個對象都有自己的showColor版本,而事實上,所有的對象都共享同一個函數(shù).為解決這個問題,開發(fā)者在工廠函數(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();
oCar2.showColor();
這樣就不需要為每一個對象都創(chuàng)建自己的showColor函數(shù),而只是創(chuàng)建指向這個函數(shù)的指針.這從功能上解決了問題,但是該函數(shù)卻不像對象的方法。于是,引出了構造函數(shù)的方式。
2.構造函數(shù)方式
構造函數(shù)與工廠函數(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);
在構造函數(shù)中,內(nèi)部無創(chuàng)建對象,而是使用this關鍵字。使用new運算符調用構造函數(shù)時,在執(zhí)行第一行代碼之前先創(chuàng)建一個對象,只有用this才能訪問這個對象。但是這會遇到什么問題呢,很顯然,它的每個對象也都會創(chuàng)建自己的showColor函數(shù)版本。為解決這個問題,引出了以下的原型方式.
3.原型方式
該方式利用了對象的prototype屬性,可把它看成創(chuàng)建新對象所依賴的原型。這里,用空構造函數(shù)來設置類名。然后把所有的方法和屬性都直接賦予prototype屬性。如下:
復制代碼 代碼如下:
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);
}
原型方式只能直接賦值,而不能通過給構造函數(shù)傳遞參數(shù)初始化屬性的值。在用這種方式時,會遇到兩個問題,不知道大家注意到?jīng)]有。第一問題是采用這種方式必須創(chuàng)建每個對象后才能改變屬性的默認值。而不能在創(chuàng)建每個對象時都會直接有自己所需要的屬性值。這點很討厭。第二個問題在于屬性所指的是對象的時候。函數(shù)共享不會出現(xiàn)任何問題,但是對象共享卻會出現(xiàn)問題。因為每個實例一般都要實現(xiàn)自己的對象。
如下面:
復制代碼 代碼如下:
var oCar1=new Car();
var oCar2=new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers);//輸出 "Mike,Sue,Matt"
alert(oCar2.drivers);//輸出"Mike,Sue,Matt"
因此drivers屬性只是指向對象的指針,所以所有的實例事實上共享同一個對象。由于出現(xiàn)這這些問題,我們引出了下面的聯(lián)合使用構造函數(shù)和原型方式。
4.混合的構造函數(shù)/原型方式
這種方式的思想是用構造函數(shù)定義對象的所有非函數(shù)屬性(包括普通屬性和指向對象的屬性),用原型方式定義對象的函數(shù)屬性(方法)。結果使得所有的函數(shù)都只被創(chuàng)建一次,而每個對象都有自己的對象屬性實例。示例代碼如下:
復制代碼 代碼如下:
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);//輸出 "Mike,Sue,Matt"
alert(oCar2.drivers);//輸出 "Mike,Sue"
由實例代碼可知,這種方式同時解決了上一種方式的兩個問題。不過,采用這種方式,仍有些開發(fā)者覺得不夠完美。
5.動態(tài)原型方式
我們可知,大多數(shù)面向對象語言都對屬性和方法進行了視覺上的封裝。而上述方式的showColor方法卻定義在了類的外面。因此,他們設計了動態(tài)原型方法。這種方式的基本思想和混合的構造函數(shù)/原型方式相同,唯一不同之處在于對象方法的位置。如下所示:
復制代碼 代碼如下:
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;
}
這種方式Car.prototype.showColor只被創(chuàng)建一次。這樣依賴,這段代碼更像其他語言中的類定義了。
6.混合工廠方式
這種方式通常是不能應該前一種方式的變通方法。它的目的是創(chuàng)建假構造函數(shù),只返回另一種對象的新實例。
復制代碼 代碼如下:
function createCar()
{
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()構造函數(shù)內(nèi)部調用了new運算符,所以自動忽略第二個new運算符。在構造函數(shù)內(nèi)部創(chuàng)建的對象被傳遞回變量var。這種方式在對象方法的內(nèi)部管理方面與經(jīng)典方式有著相同的問題。所以強烈建議:除非萬不得已,還是避免使用這種方式。
您可能感興趣的文章:
- Nodejs學習筆記之Global Objects全局對象
- JavaScript中的全局對象介紹
- javascript中全局對象的isNaN()方法使用介紹
- javascript中全局對象的parseInt()方法使用介紹
- 淺析JavaScript中兩種類型的全局對象/函數(shù)
- Javascript 陷阱 window全局對象
- js 多種變量定義(對象直接量,數(shù)組直接量和函數(shù)直接量)
- javascript 對象的定義方法
- Javascript創(chuàng)建自定義對象 創(chuàng)建Object實例添加屬性和方法
- javascript 對象定義方法 簡單易學
- Javascript 中創(chuàng)建自定義對象的方法匯總
- JavaScript定義全局對象的方法示例
相關文章
使用javascript:將其它類型值轉換成布爾類型值的解決方法詳解
本篇文章是對使用javascript:將其它類型值轉換成布爾類型值的解決方法進行了詳細的分析介紹。需要的朋友參考下2013-05-05Javascript四舍五入Math.round()與Math.pow()使用介紹
本文為大家介紹下Javascript中的四舍五入Math.round()與Math.pow()的使用,感興趣的朋友不要錯過2013-12-12Javascript獲取background屬性中url的值
Javascript獲取CSS中屬性值方法有很多,今天工作的時候遇到了一個問題是需要利用Javascript獲取css中background-img屬性url的值,通過查閱網(wǎng)站的資料找到了解決方法,現(xiàn)在將方法分享給大家,有需要的朋友們們可以參考借鑒,下面來一起看看吧。2016-10-10