JavaScript 面向?qū)ο缶幊蹋?) 基礎(chǔ)
更新時(shí)間:2010年05月18日 01:13:43 作者:
自從有了Ajax這個(gè)概念,JavaScript作為Ajax的利器,其作用一路飆升。JavaScript最基本的使用,以及語(yǔ)法、瀏覽器對(duì)象等等東東在這里就不累贅了。把主要篇幅放在如何實(shí)現(xiàn)JavaScript的面向?qū)ο缶幊谭矫妗?/div>
1. 用JavaScript實(shí)現(xiàn)類
JavaScritpt沒(méi)有專門的機(jī)制實(shí)現(xiàn)類,這里是借助它的函數(shù)允許嵌套的機(jī)制來(lái)實(shí)現(xiàn)類的。一個(gè)函數(shù)可以包含變量,又可以包含其它函數(shù),這樣,變量可以作為屬性,內(nèi)部的函數(shù)就可以作為成員方法了。因此外層函數(shù)本身就可以作為一個(gè)類了。如下:
function myClass()
{
//此處相當(dāng)于構(gòu)造函數(shù)
}
這里 myClass就是一個(gè)類。其實(shí)可以把它看成類的構(gòu)造函數(shù)。至于非構(gòu)造函數(shù)的部分,以后會(huì)詳細(xì)描述。
2. 如何獲得一個(gè)類的實(shí)例
實(shí)現(xiàn)了類就應(yīng)該可以獲得類的實(shí)例,JavaScript提供了一個(gè)方法可以獲得對(duì)象實(shí)例。即 new操作符。其實(shí)JavaScript中,類和函數(shù)是同一個(gè)概念,當(dāng)用new操作一個(gè)函數(shù)時(shí)就返回一個(gè)對(duì)象。如下:
var obj1 = new myClass();
3. 對(duì)象的成員的引用
在JavaScript中引用一個(gè)類的屬性或方法的方法有以下三種。
1> 點(diǎn)號(hào)操作符
這是一種最普遍的引用方式,就不累贅。即如下形式:
對(duì)象名.屬性名;
對(duì)象名.方法名;
2> 方括號(hào)引用
JavaScript中允許用方括號(hào)引用對(duì)象的成員。如下:
對(duì)象名["屬性名"];
對(duì)象名["方法名"];
這里方括號(hào)內(nèi)是代表屬性或方法名的字符串,不一定是字符串常量。也可以使用變量。這樣就可以使用變量傳遞屬性或方法名。為編程帶來(lái)了方便。在某些情況下,代碼中不能確定要調(diào)用那個(gè)屬性或方法時(shí),就可以采用這種方式。否則,如果使用點(diǎn)號(hào)操作符,還需要使用條件判斷來(lái)調(diào)用屬性或方法。
另外,使用方括號(hào)引用的屬性和方法名還可以以數(shù)字開(kāi)頭,或者出現(xiàn)空格,而使用點(diǎn)號(hào)引用的屬性和方法名則遵循標(biāo)示符的規(guī)則。但一般不提倡使用非標(biāo)示符的命名方法。
3> 使用eval函數(shù)
如果不希望使用變量傳遞變量或方法名,又不想使用條件判斷,那么eval函數(shù)是一個(gè)好的選擇。eval接收一個(gè)字符串類型的參數(shù),然后將這個(gè)字符串作為代碼在上下文中執(zhí)行,返回執(zhí)行的結(jié)果。這里正是利用了eval的這一功能。如下:
alert(eval("對(duì)象名." + element.value));
4. 對(duì)對(duì)象屬性,方法的添加、修改和刪除操作
JavaScript中,在生成對(duì)象之后還可以為對(duì)象動(dòng)態(tài)添加、修改和刪除屬性和方法,這與其它面向?qū)ο蟮恼Z(yǔ)言是不同的。
1> 添加屬性和方法
先創(chuàng)建一個(gè)對(duì)象,空對(duì)象創(chuàng)建后沒(méi)有任何屬性和方法,然而我們可以在代碼中創(chuàng)建。
var obj1 = new Object();
//添加屬性
obj1.ID = 1;
obj1.Name = "johnson";
//添加方法
obj1.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
2> 修改屬性與方法
與添加屬性和方法類似,例如接著上面的例子:
// 修改屬性
obj1.ID = 2;
obj1.Name = "Amanda";
// 修改方法
obj1.showMessage = function()
{
alert("ID: " + this.ID");
}
3> 刪除屬性與方法
直接將要?jiǎng)h除的屬性或方法賦值為undefined即可:
obj1.ID = 1;
obj1.Name = undefined;
obj1.showMessage = undefined;
5. 創(chuàng)建無(wú)類型對(duì)象。
類似于C#3.0里的Anonymous Types,JavaScript 也可以創(chuàng)建無(wú)類型的對(duì)象。形式如下:
var obj1 = {};
var obj2 =
{
ID: 1,
Name: "Johnson",
showMessage: function()
{
alert("ID: " + this.ID + "Name: " + this.Name);
}
}
這里定義了兩個(gè)無(wú)類型的對(duì)象,obj1和obj2。其中obj1是一個(gè)空對(duì)象。obj2包括兩個(gè)屬性ID, Name和一個(gè)方法showMessage。每個(gè)屬性和方法用逗號(hào)分割。屬性(方法)名和其值之間用分號(hào)分割。
用這種方式創(chuàng)建屬性方法時(shí),也可以用字符串定義屬性方法的名字。如:
var obj2 =
{
"ID" : 1,
"Name": "Johnson"
}
6. prototype
每個(gè)函數(shù)對(duì)象都具有一個(gè)子對(duì)象prototype,因?yàn)楹瘮?shù)也可以表示類,所以prototype表示一個(gè)類的成員的集合。當(dāng)new 一個(gè)對(duì)象時(shí),prototype對(duì)象的成員都會(huì)被實(shí)例化成對(duì)象的成員。先看一個(gè)例子:
function myClass()
{ }
myClass.prototype.ID = 1;
myClass.prototype.Name = "johnson";
myClass.prototype.showMessage = function()
{
alert("ID: " + this.ID + "Name: " + this.Name);
}
var obj1 = new myClass();
obj1.showMessage();
使用prototype對(duì)象創(chuàng)建類有一個(gè)好處。如果將所有的成員直接寫(xiě)在類的聲明中,如下:
function myClass()
{
//添加屬性
this.ID = 1;
this.Name = "johnson";
//添加方法
this.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
}
var obj1 = new myClass();
var obj2 = new myClass();
在上面的代碼中,定義了一個(gè)類myClass,在類中直接定義了兩個(gè)屬性和一個(gè)方法。然后實(shí)例化了兩個(gè)對(duì)象,這里的兩個(gè)屬性和一個(gè)方法,每創(chuàng)建一次myClass對(duì)象都會(huì)被創(chuàng)建一次,浪費(fèi)了內(nèi)存空間。而用prototype以后就可以解決這個(gè)問(wèn)題,每new一個(gè)函數(shù)時(shí),其prototype對(duì)象的成員都會(huì)自動(dòng)賦給這個(gè)對(duì)象,當(dāng)new多個(gè)對(duì)象時(shí)不會(huì)重復(fù)創(chuàng)建。
由于prototype的初始化發(fā)生在函數(shù)體執(zhí)行之前,用以下代碼可以證明:
function myClass()
{
//此處相當(dāng)于構(gòu)造函數(shù)
this.ID = 1;
this.Name1 = this.Name;
this.showMessage();
}
myClass.prototype.Name = "johnson";
myClass.prototype.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
var obj1 = new myClass();
執(zhí)行以上代碼可以發(fā)現(xiàn)當(dāng)new這個(gè)類型的對(duì)象時(shí),即彈出了對(duì)話框。
最后只得一提的是,prototype有一個(gè)方法,在面向?qū)ο蟮脑O(shè)計(jì)中用得到。即:constructor屬性,是對(duì)構(gòu)造函數(shù)的調(diào)用,這里的構(gòu)造函數(shù)即上文提到的類的聲明里的代碼。如:
function myClass()
{
//此處相當(dāng)于構(gòu)造函數(shù)
alert("this is in constructor");
}
myClass.prototype.constructor();
var obj1 = new myClass();
執(zhí)行以上代碼你會(huì)發(fā)現(xiàn)對(duì)話框彈出了兩次。由此可見(jiàn),prototype可專門用于設(shè)計(jì)類的成員,實(shí)際上在JavaScript面向?qū)ο蟮脑O(shè)計(jì)中,很多時(shí)候都會(huì)用到prototype。
JavaScritpt沒(méi)有專門的機(jī)制實(shí)現(xiàn)類,這里是借助它的函數(shù)允許嵌套的機(jī)制來(lái)實(shí)現(xiàn)類的。一個(gè)函數(shù)可以包含變量,又可以包含其它函數(shù),這樣,變量可以作為屬性,內(nèi)部的函數(shù)就可以作為成員方法了。因此外層函數(shù)本身就可以作為一個(gè)類了。如下:
復(fù)制代碼 代碼如下:
function myClass()
{
//此處相當(dāng)于構(gòu)造函數(shù)
}
這里 myClass就是一個(gè)類。其實(shí)可以把它看成類的構(gòu)造函數(shù)。至于非構(gòu)造函數(shù)的部分,以后會(huì)詳細(xì)描述。
2. 如何獲得一個(gè)類的實(shí)例
實(shí)現(xiàn)了類就應(yīng)該可以獲得類的實(shí)例,JavaScript提供了一個(gè)方法可以獲得對(duì)象實(shí)例。即 new操作符。其實(shí)JavaScript中,類和函數(shù)是同一個(gè)概念,當(dāng)用new操作一個(gè)函數(shù)時(shí)就返回一個(gè)對(duì)象。如下:
var obj1 = new myClass();
3. 對(duì)象的成員的引用
在JavaScript中引用一個(gè)類的屬性或方法的方法有以下三種。
1> 點(diǎn)號(hào)操作符
這是一種最普遍的引用方式,就不累贅。即如下形式:
對(duì)象名.屬性名;
對(duì)象名.方法名;
2> 方括號(hào)引用
JavaScript中允許用方括號(hào)引用對(duì)象的成員。如下:
對(duì)象名["屬性名"];
對(duì)象名["方法名"];
這里方括號(hào)內(nèi)是代表屬性或方法名的字符串,不一定是字符串常量。也可以使用變量。這樣就可以使用變量傳遞屬性或方法名。為編程帶來(lái)了方便。在某些情況下,代碼中不能確定要調(diào)用那個(gè)屬性或方法時(shí),就可以采用這種方式。否則,如果使用點(diǎn)號(hào)操作符,還需要使用條件判斷來(lái)調(diào)用屬性或方法。
另外,使用方括號(hào)引用的屬性和方法名還可以以數(shù)字開(kāi)頭,或者出現(xiàn)空格,而使用點(diǎn)號(hào)引用的屬性和方法名則遵循標(biāo)示符的規(guī)則。但一般不提倡使用非標(biāo)示符的命名方法。
3> 使用eval函數(shù)
如果不希望使用變量傳遞變量或方法名,又不想使用條件判斷,那么eval函數(shù)是一個(gè)好的選擇。eval接收一個(gè)字符串類型的參數(shù),然后將這個(gè)字符串作為代碼在上下文中執(zhí)行,返回執(zhí)行的結(jié)果。這里正是利用了eval的這一功能。如下:
alert(eval("對(duì)象名." + element.value));
4. 對(duì)對(duì)象屬性,方法的添加、修改和刪除操作
JavaScript中,在生成對(duì)象之后還可以為對(duì)象動(dòng)態(tài)添加、修改和刪除屬性和方法,這與其它面向?qū)ο蟮恼Z(yǔ)言是不同的。
1> 添加屬性和方法
先創(chuàng)建一個(gè)對(duì)象,空對(duì)象創(chuàng)建后沒(méi)有任何屬性和方法,然而我們可以在代碼中創(chuàng)建。
復(fù)制代碼 代碼如下:
var obj1 = new Object();
//添加屬性
obj1.ID = 1;
obj1.Name = "johnson";
//添加方法
obj1.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
2> 修改屬性與方法
與添加屬性和方法類似,例如接著上面的例子:
復(fù)制代碼 代碼如下:
// 修改屬性
obj1.ID = 2;
obj1.Name = "Amanda";
// 修改方法
obj1.showMessage = function()
{
alert("ID: " + this.ID");
}
3> 刪除屬性與方法
直接將要?jiǎng)h除的屬性或方法賦值為undefined即可:
復(fù)制代碼 代碼如下:
obj1.ID = 1;
obj1.Name = undefined;
obj1.showMessage = undefined;
5. 創(chuàng)建無(wú)類型對(duì)象。
類似于C#3.0里的Anonymous Types,JavaScript 也可以創(chuàng)建無(wú)類型的對(duì)象。形式如下:
復(fù)制代碼 代碼如下:
var obj1 = {};
var obj2 =
{
ID: 1,
Name: "Johnson",
showMessage: function()
{
alert("ID: " + this.ID + "Name: " + this.Name);
}
}
這里定義了兩個(gè)無(wú)類型的對(duì)象,obj1和obj2。其中obj1是一個(gè)空對(duì)象。obj2包括兩個(gè)屬性ID, Name和一個(gè)方法showMessage。每個(gè)屬性和方法用逗號(hào)分割。屬性(方法)名和其值之間用分號(hào)分割。
用這種方式創(chuàng)建屬性方法時(shí),也可以用字符串定義屬性方法的名字。如:
復(fù)制代碼 代碼如下:
var obj2 =
{
"ID" : 1,
"Name": "Johnson"
}
6. prototype
每個(gè)函數(shù)對(duì)象都具有一個(gè)子對(duì)象prototype,因?yàn)楹瘮?shù)也可以表示類,所以prototype表示一個(gè)類的成員的集合。當(dāng)new 一個(gè)對(duì)象時(shí),prototype對(duì)象的成員都會(huì)被實(shí)例化成對(duì)象的成員。先看一個(gè)例子:
復(fù)制代碼 代碼如下:
function myClass()
{ }
myClass.prototype.ID = 1;
myClass.prototype.Name = "johnson";
myClass.prototype.showMessage = function()
{
alert("ID: " + this.ID + "Name: " + this.Name);
}
var obj1 = new myClass();
obj1.showMessage();
使用prototype對(duì)象創(chuàng)建類有一個(gè)好處。如果將所有的成員直接寫(xiě)在類的聲明中,如下:
復(fù)制代碼 代碼如下:
function myClass()
{
//添加屬性
this.ID = 1;
this.Name = "johnson";
//添加方法
this.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
}
var obj1 = new myClass();
var obj2 = new myClass();
在上面的代碼中,定義了一個(gè)類myClass,在類中直接定義了兩個(gè)屬性和一個(gè)方法。然后實(shí)例化了兩個(gè)對(duì)象,這里的兩個(gè)屬性和一個(gè)方法,每創(chuàng)建一次myClass對(duì)象都會(huì)被創(chuàng)建一次,浪費(fèi)了內(nèi)存空間。而用prototype以后就可以解決這個(gè)問(wèn)題,每new一個(gè)函數(shù)時(shí),其prototype對(duì)象的成員都會(huì)自動(dòng)賦給這個(gè)對(duì)象,當(dāng)new多個(gè)對(duì)象時(shí)不會(huì)重復(fù)創(chuàng)建。
由于prototype的初始化發(fā)生在函數(shù)體執(zhí)行之前,用以下代碼可以證明:
復(fù)制代碼 代碼如下:
function myClass()
{
//此處相當(dāng)于構(gòu)造函數(shù)
this.ID = 1;
this.Name1 = this.Name;
this.showMessage();
}
myClass.prototype.Name = "johnson";
myClass.prototype.showMessage = function()
{
alert("ID: " + this.ID + ", Name: " + this.Name);
}
var obj1 = new myClass();
執(zhí)行以上代碼可以發(fā)現(xiàn)當(dāng)new這個(gè)類型的對(duì)象時(shí),即彈出了對(duì)話框。
最后只得一提的是,prototype有一個(gè)方法,在面向?qū)ο蟮脑O(shè)計(jì)中用得到。即:constructor屬性,是對(duì)構(gòu)造函數(shù)的調(diào)用,這里的構(gòu)造函數(shù)即上文提到的類的聲明里的代碼。如:
復(fù)制代碼 代碼如下:
function myClass()
{
//此處相當(dāng)于構(gòu)造函數(shù)
alert("this is in constructor");
}
myClass.prototype.constructor();
var obj1 = new myClass();
執(zhí)行以上代碼你會(huì)發(fā)現(xiàn)對(duì)話框彈出了兩次。由此可見(jiàn),prototype可專門用于設(shè)計(jì)類的成員,實(shí)際上在JavaScript面向?qū)ο蟮脑O(shè)計(jì)中,很多時(shí)候都會(huì)用到prototype。
相關(guān)文章
javascript 模式設(shè)計(jì)之工廠模式學(xué)習(xí)心得
接口的實(shí)現(xiàn),從而使不同子類可以被同等的對(duì)待,恰當(dāng)?shù)氖褂霉S模式,但不要拘泥與形式,理解本質(zhì)。2010-04-04
JavaScript 面向?qū)ο蟮闹接谐蓡T和公開(kāi)成員
這節(jié)來(lái)說(shuō)下JavaScript的私有成員和公開(kāi)成員,雖然JavaScript沒(méi)有private和public關(guān)鍵字,但還是那句話——作為開(kāi)發(fā)人員我們要有面向?qū)ο蟮乃枷耄?2010-05-05
編寫(xiě)可維護(hù)面向?qū)ο蟮腏avaScript代碼[翻譯]
編寫(xiě)可維護(hù)面向?qū)ο蟮腏avaScript代碼[翻譯],學(xué)習(xí)js面向?qū)ο缶帉?xiě)的朋友可以參考下。
2011-02-02
javascript中類的定義及其方式(《javascript高級(jí)程序設(shè)計(jì)》學(xué)習(xí)筆記)
javascript也是一種面向?qū)ο蟮木幊陶Z(yǔ)言。但是javascript中的類相關(guān)的東西(類的定義,原型鏈,繼承等)卻不是很好理解,特別是繼承。
2011-07-07
JavaScript面象對(duì)象設(shè)計(jì)
學(xué)習(xí)js的高境界就是使用面向?qū)ο蟮姆椒?,?shí)現(xiàn)js的調(diào)用
2008-04-04
JavaScript 面向?qū)ο笕腴T精簡(jiǎn)篇
圍繞面向?qū)ο蟮膸状箨P(guān)鍵字:封裝 ,繼承 ,多態(tài) ,展開(kāi)JavaScript面向?qū)ο?/div> 2009-03-03

