JavaScript面向對象編程(2)-- 類的定義
最近這一段時間事情太多了,沒有時間再繼續寫,幸好這兩天有點小閑,先小寫一下JavaScript中面向對象一中推薦的方法。本文承接上一篇JavaScript面向對象編程(1) -- 基礎。??? 上篇說過,JavaScript沒有類的概念,需要通過函數來實現類的定義。先通過一個例子說明:





















? var?obj2 =?new?myClass();
??? function的定義實際上相當于類的構造函數,最后兩句是創建這個類的實例。先分析第一句:var?obj1?=?new?myClass(); 當用new創建類的實例時,解釋器首先會創建一個空的對象。然后運行這個myClass函數,并將this指針指向這個類的實例。當碰到this.ID?=?id;和this.Name?=?name;及this.showMessage?=?function(){...}時,便會創建這兩個屬性,和這個方法,并把變量id,name的值一級函數的定義賦給這兩個屬性及這個函數對象(shwoMessage)。這個過程相當于初始化這個對象,類似于C# 中的構造函數。最后new返回這個對象。再看第二句:var?obj2 =?new?myClass(); 執行過程與上一句代碼相同,即創建一個空對象,然后執行myClass這個函數,定義兩個屬性和一個方法。
???
??? 從上面的分析中可以看到,上面這種實現類的方式,即在函數的定義中定義類的屬性方法。存在著弊端。如果需要創建兩個或更多這個類的實例時,上文是兩個,這些屬性會被重復的創建多次。
???
??? 那么如何避免這種情況呢?上一篇中也曾提到過用prototype。prototype和它的名字一樣是一個原型,每一個function都有一個子對象prototype,它其實表示這個function對象的成員的集合,由于這里我們使用function實現類的,所以可以說prototype其實就是便是類的成員的集合。prototype定義的屬性和方法執行在函數的構造體執行之前,所以當new一個對象之前,其實prototype的成員已經執行過了。先看一個例子:























??? 類的結構還是和前面的例子相同,只不過這里是利用了prototype來實現。還是先看最后兩句,前面說過,prototype是執行在函數構造體之前,即執行到var?obj1?=?new?myClass();之前,這個類已經有了ID,Name屬性和showMessage方法。執行者一句時執行過程如下,注意和前一個例子比較:首先還是創建一個空的對象,并把this指針指向這個對象。然后將函數的prototype對象的所有成員都賦給這個對象(注意沒有再創建這些成員)。然后執行函數體。最后new返回這個對象。執行下一句時:同樣執行此過程,不會重復創建這些成員。
???
??? 上面的代碼還只是一個例子,在實際的項目中,可能出現的是類中有大量的成員,同時可能需要創建大量的實例。這是prototype就會顯示其優越性了。另外上面的代碼中使用了大括號語法定義了prototype的成員,這樣看起來代碼更清晰。這是一種比較推薦的類的設計模式。當然在眾多的項目中,可能還會發現更好的模式,我們也希望能有更優化的JavaScript的編程模式不斷推陳出新,也希望隨著時間的推移,各主流瀏覽器也對JavaScript的解析都標準,統一。
??? 上面說過prototype定義的成員是發生在構造體之前,可以證明一下,在上面的例子中,構造體是空的,在構造函數中加入一句alert(this.Name);,當執行到var?obj1?=?new?myClass();時,會看到彈出對話框,顯示正確的屬性值。
????? 寫了這段文字之后承蒙多為兄弟的點評,收獲匪淺。對上面的例子進一步討論,如下代碼:





































??? 所以借用prototype定義類時,依然需要將屬性定義在構造體中,而將方法定義在該構造體的原型上。如下:

































???? 關于私有成員,共有成員以及靜態成員,類的繼承,抽象類,虛方法,類的反射等實現方法,以后還會堅持寫下去。不過我覺得需要說一下的是,我打算寫的是JavaScript面向對象的基礎實現,如果需要深入的學習建議參考李戰老哥的“甘露模型”。
posted on 2009-12-08 15:40 飛熊 閱讀(262) 評論(0) 編輯 收藏 所屬分類: javaScript