2016-03-18 174 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