2012-06-30 51 views
5

我試圖創建一個新類Dog是通過原型繼承繼承了Animal類:爲什麼我不能在JavaScript代碼中繼承Animal類的原型?

function Animal() { 
    this.name = "animal"; 
    this.writeName = function() { 
    document.write(this.name); 
    }  
} 

function Dog() { 
    this.name = "dog"; 
    this.prototype = new Animal(); 
} 

new Dog().writeName() 

JS Fiddle

不過,我得到一個JavaScript錯誤:Uncaught TypeError: Object #<Dog> has no method 'say'

爲什麼? Dog對象不應該保留Animal對象作爲原型嗎?

+0

你肯定你粘貼正確的代碼?單詞'say'不會在那裏出現一次。 –

+0

因爲沒有課? ;)但問題是'this'已經是*錯誤的對象*(以及[[原型]]爲時太晚而不能用於'new')。 – 2012-06-30 01:32:14

+2

順便說一句,使用console.log而不是document.write和alert。從長遠來看,這會讓你的生活變得更加輕鬆。 – hugomg

回答

3

@瑞安的答案是正確的,當然,但他並沒有真正什麼是它不同,它可能不是很清楚一個初學者,所以......

的你正在做的錯誤是this.prototype = new Animal();分配一個Animal實例到對當前Dog實例(由this簡稱)命名prototype財產,但沒有什麼特別的命名屬性3210在這方面。

prototype屬性只是神奇的功能對象。當您使用new SomeFunc()新對象的內部/隱藏[原型]]指針將指向對象通過SomeFunc.prototype指出了SomeFunc一個新的實例。 prototype名稱在任何其他上下文中都不是特殊的。

+1

yea很匆忙謝謝澄清他。 – Ryan

2

「原型」屬性僅僅是一個普通的屬性。與委託交易的真實[[原]]屬性是隱藏的,並且不能被創建之後的對象(除了一些擴展:在Firefox,其__proto__屬性)可直接操作。

正確的Javascript繼承的例子,在本質上你正在做的會使用的Object.create來創建一個狗正確的[[原型]]屬性什麼類似:

function Animal() { 
    this.name = "animal"; 
    this.writeName = function() { 
    document.write(this.name); 
    }  
} 

function Dog() { 
    var dog = Object.create(new Animal()) 
    dog.name = "dog"; 
    return dog; 
} 

(new Dog()).writeName() 

更地道的例子將是像Ryan的答案,但我會建議使用的Object.create代替new Animal實例狗原型,我會把動物的方法,在一個單獨的動物原型,而不是手動安裝它們的構造就像你在做什麼。

+0

@pst:我在談論他如何期待「原型」屬性的行爲。 – hugomg

+0

好吧,那最好不過了,+1 :-)是'的Object.create(原)'在第3版[本地]可用的有關係嗎? – 2012-06-30 01:37:39

+0

@pst:現在我不記得了,但是當它不可用時,它很容易爲它編寫一個polyfill:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create#Polyfill – hugomg

7
function Animal() { 
    this.name = "animal"; 
    this.writeName = function() { 
    document.write(this.name); 
    }  
} 

function Dog() { 
    this.name = "dog"; 

} 
Dog.prototype = new Animal(); 
dog = new Dog(); 
dog.writeName(); 

現在狗有動物的所有屬性。

jsfiddle

相關問題