2010-03-19 122 views
3

這是關於JavaScript中的「繼承」。JavaScript中的構造函數和繼承

假設我創建一個構造鳥(),和另一個叫鸚鵡(),我做,通過設定它的一個實例鸚鵡的原型,如下面的代碼「繼承」鳥的性質表明:

function Bird() { 
    this.fly = function(){}; 
} 

function Parrot() { 
    this.talk = function(){ alert("praa!!"); }; 
} 
Parrot.prototype = new Bird(); 

var p = new Parrot(); 

p.talk(); // Alerts "praa!!" 
alert(p.constructor); // Alerts the Bird function!?!?! 

當我創建了一個Parrot實例後,它爲什麼是Bird()的.constructor屬性,而不是Parrot(),它是我用來創建對象的構造函數?

+0

現代火狐,Chrome,IEXPLORER和Safari測試了相同的結果...:P – nandinga

回答

3

原型是一個對象,就像JavaScript中的任何其他對象一樣,對象分配是通過引用的。你剛剛給鸚鵡的原型分配了一隻新的鳥,所以鸚鵡的原型現在成了一隻鳥。 Bird的構造函數是Bird。

你可以用線

Parrot.prototype.constructor = Parrot; 

另一種方式做,這將是分配解決這個鳥的原型的克隆Parrot.prototype

function deepClone(obj) { 
    var clone = {}; 
    for(var i in obj) { 
     if(typeof(obj[i])==="object") { 
      clone[i] = deepClone(obj[i]); 
     } else { 
      clone[i] = obj[i]; 
     } 
    } 
    return clone; 
} 


Parrot.prototype = deepClone(Bird.prototype); 
Parrot.prototype.constructor = Parrot; 

我喜歡這一點,因爲:

1)它節省了創建一個任意的鳥的實例(如果有東西正在計數許多鳥已經創建)

2)如果Bird構造函數接受了在構造函數體中測試過的參數會怎麼樣?然後 電話:

Parrot.prototype = new Bird(); 

然後可以導致空指針

+0

啊!我終於明白了:p Parrot.prototype是一個帶有.constructor的Bird實例,已經定義(等於Bird),用於Parrot創建新實例。 我覺得很奇怪的是.constructor不會自動覆蓋。無論如何,知道它很容易解決(就像你提出的那樣)。 非常感謝! – nandinga

1

構造函數引用創建實例的原型(而不是實例)的函數。