javascript prototype分析
我說(shuō)不盡然,意思是說(shuō)理解Prototype的一般用法很簡(jiǎn)單。但是真正能做到融會(huì)貫通理解Prototype確實(shí)是件很難的事情。
今天我就從Prototype的基本開(kāi)始講。上文中我講了原型模式。其實(shí)在Javascript中原型也是這個(gè)意思。 Javascript中對(duì)象的原型屬性的解釋是:返回對(duì)象類(lèi)型原型的引用。這是一個(gè)暈人的解釋。其實(shí)就是指定了一個(gè)需要復(fù)制的對(duì)象。
文字再多也不如代碼,上代碼,說(shuō)最簡(jiǎn)單的,任何類(lèi)都繼承自O(shè)bject類(lèi):
function A()
{
//todo something
}
A.prototype=new Object();
其實(shí)這樣就相當(dāng)于Object對(duì)象是A的一個(gè)原型,這樣就相當(dāng)于了把Object對(duì)象的屬性和方法復(fù)制到了A上,和原型模式的精髓一樣吧!
好,大概了解了prototype的基本用法,我們來(lái)看看原型究竟有什么用處。
最簡(jiǎn)單的用法,動(dòng)態(tài)擴(kuò)展類(lèi)的方法和屬性。
de>function People()
{
this.Jump=function(){
alert("I can jump");
}
}
現(xiàn)在要擴(kuò)充方法:
People.prototype.Run=function(){
alert("I can run,too");
}
好,測(cè)試下:
var p=new People();
p.Jump();
p.Run();
cript玩轉(zhuǎn)Prototype - Gabriel - Software Engineer" height=153 alt="Javas
cript玩轉(zhuǎn)Prototype - Gabriel - Software Engineer" height=138 alt="Javas
接下來(lái),順帶講一下Javascript的方法種類(lèi)。我個(gè)人將Javascript的方法分為三種:
<1>類(lèi)方法
<2>對(duì)象方法
<3>原型方法
先看代碼,后講區(qū)別:
function People(name)
{
this.name=name;
//對(duì)象方法
this.Introduce=function(){
alert("My name is "+this.name);
}
}
//類(lèi)方法
People.Run=function(){
alert("I can run");
}
//原型方法
People.prototype.IntroduceChinese=function(){
alert(" 我的名字是"+this.name);
}
測(cè)試下:
var p1=new People("Windking");
p1.Introduce();
People.Run();
p1.IntroduceChinese();
cript玩轉(zhuǎn)Prototype - Gabriel - Software Engineer" height=124 alt="Javas
cript玩轉(zhuǎn)Prototype - Gabriel - Software Engineer" height=140 alt="Javas
cript玩轉(zhuǎn)Prototype - Gabriel - Software Engineer" height=136 alt="Javas
總結(jié)下:
名稱(chēng)
位置
格式
類(lèi)方法
類(lèi)外
類(lèi)名.方法名
對(duì)象方法
類(lèi)內(nèi)
this.方法名
原型方法
類(lèi)外
類(lèi)名.prototype.方法名
我們用C#來(lái)做類(lèi)別來(lái)講解這三個(gè)方法:
類(lèi)方法其實(shí)就是我們講的靜態(tài)方法:
如public static void Run(){}
而對(duì)象方法其實(shí)就是實(shí)例方法。
public void Introduce(){}
而原型方法有所不同,由于C#中不允許動(dòng)態(tài)為對(duì)象增加方法,因此在C#中并不存在原型方法。原型方法處于C#的靜態(tài)方法與實(shí)例方法之間,通過(guò)對(duì)象調(diào)用,但是存儲(chǔ)的內(nèi)存形式卻類(lèi)似于靜態(tài)方法,也就是所有實(shí)例對(duì)象共享同一副本。
(ps:盡量將方法定義為原型方法,原型方法避免了每次調(diào)用構(gòu)造函數(shù)時(shí)對(duì)屬性或方法的構(gòu)造,因此比較節(jié)省空間和時(shí)間)
p1.IntroduceChinese();創(chuàng)建對(duì)象。
還記得我在上一篇文章里講的淺復(fù)制么?為什么大家都喜歡批量生產(chǎn)?效率是最主要因素。淺復(fù)制也一樣,我們?yōu)槭裁匆獪\復(fù)制,因?yàn)樾矢摺W鳛樵湍J降?Javascript應(yīng)用,prototype也承擔(dān)著這樣的重任。用prototype來(lái)創(chuàng)建對(duì)象,要比其他方式快得多。
看代碼例子:
function People(name,age)
{
this.name=name;
this.age=age;
}
var p1=new People("Xuan",22);
var girls=[ ];
var GirlPrototype=function(){};
GirlPrototype.prototype=p1;
for(var i=0;i<100000;i++)
{
girls[i]=new GirlPrototype();
}
玩轉(zhuǎn)繼承:
Prototype最大的應(yīng)用其實(shí)還是在于玩轉(zhuǎn)繼承,這個(gè)在此不討論,請(qǐng)參加我的另一篇文章:《Javascript玩轉(zhuǎn)繼承(二)》。
好,基本的應(yīng)用說(shuō)完,下面我來(lái)說(shuō)一下prototype的天使和魔鬼兩面。
說(shuō)prototype是天使,是因?yàn)橐陨系膸c(diǎn)應(yīng)用,讓Javascript增加了很大的靈活性,尤其原型繼承,更是Javascript最多的繼承方式。
說(shuō)他是魔鬼,則是因?yàn)橄旅鎺追矫妫?/p>
原型繼承的缺陷。請(qǐng)參見(jiàn)《Javascript玩轉(zhuǎn)繼承(二)》。
原型其實(shí)相當(dāng)于原型模式中的淺復(fù)制,因此也會(huì)造成牽一發(fā)而動(dòng)全身的效果。
過(guò)于靈活。為什么過(guò)于靈活呢?其實(shí)這點(diǎn)是針對(duì)第一點(diǎn)來(lái)說(shuō)的,能夠動(dòng)態(tài)地添加屬性和方法固然是增加了靈活性。可是我們討論一種情況,100個(gè)人同時(shí)來(lái)開(kāi)發(fā)一個(gè)Javascript的項(xiàng)目,很多沒(méi)經(jīng)驗(yàn)的人愛(ài)上了玩轉(zhuǎn)prototype,一個(gè)人往這個(gè)類(lèi)里加一個(gè)方法,還面向?qū)ο竺矗?