2016-03-18 216 views
1

下面是一個簡單的JavaScript繼承例子。我們可以替換這一行:Dog.prototype = new Animal();
與Dog.prototype = Animal.prototype?JavaScript原型繼承

我已經在瀏覽器中測試過了,他們給了我相同的結果。我很奇怪爲什麼我們需要創建一個新的Animal對象並將它分配給Dog.prototype。與call

function Dog(color, age) { 
    this.color = color; 
    Animal.call(this, age); // This line 
} 

在這裏,你打電話動物的構造提供它this從而手動建立動物的上下文:

function Animal(age){ 
    this.age = age; 
} 

Animal.prototype.walk = function(){ 
    console.log("Walk"); 
} 

function Dog(color, age){ 
    this.color = color; 
    Animal.call(this, age) 
} 

Dog.prototype = new Animal();  //Why not Dog.prototype = Animal.prototype 
Dog.prototype.constructor = Dog; 


dog_b = new Dog("yellow", 9); 
console.log("Age: " + dog_b.age + " Color: " + dog_b.color); 
dog_b.walk() 
+0

「*我很奇怪爲什麼我們需要創建一個新的動物對象*」 - 良好的直覺。你[不應該在那裏使用'new Animal'](https://stackoverflow.com/questions/12592913/what-is-the-reason-to-use-the-new-keyword-here)。 – Bergi

回答

2

在這種特殊情況下,你可以爲一個簡單的理由更換線路。 thisfunction Animal將始終指Dog的對象。這就是爲什麼一個new不會有所作爲。

嚴格地說,你實際上並沒有做適當的原型繼承。您可以確認這樣做:

dog_b.hasOwnProperty('age'); // => true 

這實際上被稱爲constructor stealing其中DogAnimal的構造。 walk方法雖然在Animal的ctor。

這意味着age屬性是Dog本身,而不是Animal。這是爲什麼?同樣,因爲您正在手動建立Animal的構造函數上下文爲Dog

編輯:

在Javascript中有描述和實現繼承的不同方法,因爲這不是一個地方寫一本書,我會很快。

你在做什麼叫Parasitic Combination Inheritance(你不必記住這個詞)。這沒有錯,它只是獲得繼承的另一種方式(僅適用於Animal.prototype功能的原型)。如果它在爲你工作,我會說拿它。如果你真的想讓AnimalageAnimal上,那麼在使用構造函數獲得繼承時會遇到問題。這樣做將是

方式一:

function inherit(o){ 
    function F(){} 
    F.prototype = o; 
    return new F(); 
} 

var foo = { 
    name: 'some' 
} 

var bar = inherit(foo); // bar.name refers to the object on foo 

正如你所看到的,原型繼承通常用於對象文本(想想角的範圍對象)。

+0

那麼,如何在沒有構造函數竊取的情況下編寫Dog()構造函數的正確方法是什麼? – user1187968

+0

我不確定你的第一行。你是否暗示'Dog.prototype = new Animal();'和'Dog.prototype = Animal.prototype'都很好?甚至,他們做同樣的事情? – Bergi

+0

我從來沒有聽說過「構造函數竊取」這個術語。鑑於'狗'應該從'動物'繼承,它只是一個* [超級](https://en.wikipedia。org/wiki/Inheritance_(object-oriented_programming)#Subclasses_and_superclasses)call *。 – Bergi