2012-01-30 40 views
6

下面的代碼看看:JavaScript繼承:何時我的派生成員在哪裏?

function Primate() { 
    this.prototype = Object; 
    this.prototype.hairy = true; 
} 

function Human() { 
    this.prototype = Primate; 
} 

new Human(); 

當你檢查new Human(),沒有hairy成員。我希望有一個。我有另外一種方法可以繼承Primate嗎?涉及Object.create()(ECMAScript5在我的場景中使用很好)?

+0

您必須閱讀JS這個理解繼承:http://javascript.crockford.com/inheritance.html和http://javascript.crockford.com/prototypal.html – bfavaretto 2012-01-30 18:56:44

+1

你這樣做是錯的。你想操縱構造函數的'prototype'對象 - 'Primate'和'Human'。新創建的實例(構造函數中的'this'值)不是*函數,因此添加'prototype'屬性是無意義的。 – 2012-01-30 19:15:15

+0

我會創建和擴展對象(用Object.create)而不是修補原型鏈的猴子。使用函數作爲構造函數可能會導致混淆,因爲它將JavaScript對象實現爲類結構。 – rxgx 2012-01-30 20:52:30

回答

4

當你的代碼編寫,使用new Human()創建的對象將有一個名爲prototype屬性,其值是對Primate函數的引用。這顯然不是你想要的(它並不特別特別)。

有幾件事情:

  • 通常你想修改功能一種旨在用作構造(與new運營商)的prototype。換句話說,您想要設置prototypeHuman(不在實例Human)。

  • 分配給prototype值應該是一個實例所需類型的(或者,如果沒有初始化的工作是必要的,需要的類型的prototype),而不是它的構造函數的引用。

  • 沒有必要明確地將Object(或Object實例)分配給函數的prototype。這是隱含的。

你可能想要更多的東西是這樣的:

function Primate() { 
    this.hairy = true; 
} 

function Human() {} 
Human.prototype = new Primate(); 
Human.prototype.constructor = Human; 

var h = new Human(); 

Human通過h引用有一個名爲hairy,其價值是真實的財產。

在前面的例子,hairy只能分配一次Primate調用它的價值,這就是爲什麼Human.prototype必須分配的Primate一個實例。這可以寫成這樣,不需要這種初始化。

例子:

function Primate() {} 
Primate.prototype.hairy = true; 

function Human() {} 
Human.prototype = Primate.prototype; 
Human.prototype.constructor = Human; 

var h = new Human();