悟透JavaScript之構造對象 (2)

這段代碼表明,函數不但可以當作構造函數,而且還可以帶參數,還可以爲對象添加成員和方法。其中的第9 行,Employee 構造函數又將自己接收的this 作爲參數調用Person 構造函數,這就是相當於調用基類的構造函數。第2122 行還表明這樣一個意思:BillGates 是由Person 構造的,而SteveJobs 是由Employee 構造的。對象內置的constructor 屬性還指明瞭構造對象所用的具體函數!

其實,如果你願意把函數當作的話,她就是,因爲她本來就有的那些特徵。難道不是嗎?她生出的兒子各個都有相同的特徵,而且構造函數也與類同名嘛!

但要注意的是,用構造函數操作this 對象創建出來的每一個對象,不但具有各自的成員數據,而且還具有各自的方法數據。換句話說,方法的代碼體(體現函數邏輯的數據)在每一個對象中都存在一個副本。儘管每一個代碼副本的邏輯是相同的,但對象們確實是各自保存了一份代碼體。上例中的最後一句說明了這一實事,這也解釋了JavaScript 中的函數就是對象的概念。

同一類的對象各自有一份方法代碼顯然是一種浪費。在傳統的對象語言中,方法函數並不象JavaScript 那樣是個對象概念。即使也有象函數指針、方法指針或委託那樣的變化形式,但其實質也是對同一份代碼的引用。一般的對象語言很難遇到這種情況。

不過,JavaScript 語言有大的靈活性。我們可以先定義一份唯一的方法函數體,並在構造this 對象時使用這唯一的函數對象作爲其方法,就能共享方法邏輯。例如:

function SayHello() //先定義一份SayHello 函數代碼

{

alert("Hello, I'm " + this.name);

};

function Person(name) //帶參數的構造函數

{

this.name = name; //將參數值賦給給this 對象的屬性

this.SayHello = SayHello; //this 對象SayHello 方法賦值爲前面那份SayHello

代碼。

};

var BillGates = new Person("Bill Gates"); //創建BillGates 對象

var SteveJobs = new Person("Steve Jobs"); //創建SteveJobs 對象

alert(BillGates.SayHello == SteveJobs.SayHello); //顯示:true

其中,最後一行的輸出結果表明兩個對象確實共享了一個函數對象。雖然,這段程序達到了共享了一份方法代碼的目的,但卻不怎麼優雅。因爲,定義SayHello 方法時反映不出其與Person 類的關係。優雅這個詞用來形容代碼,也不知道是誰先提出來的。不過,這個詞反映了程序員已經從追求代碼的正確、高效、可靠和易讀等基礎上,向着追求代碼的美觀感覺和藝術境界的層次發展,程序人生又多了些浪漫色彩。

顯然,JavaScript 早想到了這一問題,她的設計者們爲此提供了一個有趣的prototype 概念。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章