prototype.js 是Sam Stephenson寫的一個非常優雅的javascript基礎類庫,對javascript做了大量的擴展,而且很好的支持Ajax,國內外有多個基于此類庫實現的效果庫,也做得很棒。 prototype.js不僅是一個有很大實用價值的js庫,而且有很高的學習價值。 --- 在prototype.js中,prototype對象是實現面向對象的一個重要機制。 每個函數就是一個對象(Function),函數對象都有一個子對象 prototype對象,類是以函數的形式來定義的。prototype表示該函數的原型,也表示一個類的成員的集合。 在通過new創建一個類的實例對象的時候,prototype對象的成員都成為實例化對象的成員。 1、該對象被類所引用,只有函數對象才可引用; 2、在new實例化后,其成員被實例化,實例對象方可調用。 同時,函數是一個對象,函數對象若直接聲明成員,不用被實例化即可調用。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
http://tech.ddvip.com/2009-05/1243588303121461.html
上文一直在羅嗦GOF的原型模式,在本文中講開始正式討論Javascript的Prototype。對于Javascript的初學者來說,Prototype是個蠻高深的話題,其實并不盡然。
我說不盡然,意思是說理解Prototype的一般用法很簡單。但是真正能做到融會貫通理解Prototype確實是件很難的事情。
今天我就從Prototype的基本開始講。上文中我講了原型模式。其實在Javascript中原型也是這個意思。Javascript中對象的原型屬性的解釋是:返回對象類型原型的引用。這是一個暈人的解釋。其實就是指定了一個需要復制的對象。
文字再多也不如代碼,上代碼,說最簡單的,任何類都繼承自Object類:
function A()
{ }
A.prototype=new Object();
其實這樣就相當于Object對象是A的一個原型,這樣就相當于了把Object對象的屬性和方法復制到了A上,和原型模式的精髓一樣吧!
好,大概了解了prototype的基本用法,我們來看看原型究竟有什么用處。
最簡單的用法,動態擴展類的方法和屬性。
function People()
{
this.Jump=function(){
alert("I can jump");
}
}
現在要擴充方法:
People.prototype.Run=function(){
alert("I can run,too");
}
好,測試下:
var p=new People();
p.Jump();
p.Run();
接下來,順帶講一下Javascript的方法種類。我個人將Javascript的方法分為三種:
<1>類方法
<2>對象方法
<3>原型方法
先看代碼,后講區別:
function People(name)
{
this.name=name;
//對象方法
this.Introduce=function(){
alert("My name is "+this.name);
}
}
//類方法
People.Run=function(){
alert("I can run");
}
//原型方法
People.prototype.IntroduceChinese=function(){
alert("我的名字是"+this.name);
}
測試下:
var p1=new People("Windking");
p1.Introduce();
People.Run();
p1.IntroduceChinese();
總結下:
名稱 | 位置 | 格式 |
類方法 | 類外 | 類名.方法名 |
對象方法 | 類內 | this.方法名 |
原型方法 | 類外 | 類名.prototype.方法名 |
我們用C#來做類別來講解這三個方法:
類方法其實就是我們講的靜態方法:
如public static void Run(){}
而對象方法其實就是實例方法。
public void Introduce(){}
而原型方法有所不同,由于C#中不允許動態為對象增加方法,因此在C#中并不存在原型方法。原型方法處于C#的靜態方法與實例方法之間,通過對象調用,但是存儲的內存形式卻類似于靜態方法,也就是所有實例對象共享同一副本。
(ps:盡量將方法定義為原型方法,原型方法避免了每次調用構造函數時對屬性或方法的構造,因此比較節省空間和時間)
p1.IntroduceChinese();創建對象。
還記得我在上一篇文章里講的淺復制么?為什么大家都喜歡批量生產?效率是最主要因素。淺復制也一樣,我們為什么要淺復制,因為效率高。作為原型模式的Javascript應用,prototype也承擔著這樣的重任。用prototype來創建對象,要比其他方式快得多。
看代碼例子:
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();
}
玩轉繼承:
Prototype最大的應用其實還是在于玩轉繼承,這個在此不討論,請參加我的另一篇文章:《Javascript玩轉繼承(二)》。
好,基本的應用說完,下面我來說一下prototype的天使和魔鬼兩面。
說prototype是天使,是因為以上的幾點應用,讓Javascript增加了很大的靈活性,尤其原型繼承,更是Javascript最多的繼承方式。
說他是魔鬼,則是因為下面幾方面:
原型繼承的缺陷。請參見《Javascript玩轉繼承(二)》。
原型其實相當于原型模式中的淺復制,因此也會造成牽一發而動全身的效果。
過于靈活。為什么過于靈活呢?其實這點我是針對第一點來說的,能夠動態地添加屬性和方法固然是增加了靈活性。可是我們討論一種情況,100個人同時來開發一個Javascript的項目,很多沒經驗的人愛上了玩轉prototype,一個人往這個類里加一個方法,還面向對象么?當然這只是我的個人之見。如果有異議,歡迎和我討論。