【问题标题】:JavaScript prototype inheritance [duplicate]JavaScript原型继承[重复]
【发布时间】:2016-07-04 16:59:45
【问题描述】:

下面是一个简单的 JavaScript 继承示例。我们可以替换以下行:Dog.prototype = new Animal();
与 Dog.prototype = Animal.prototype?

我在浏览器中进行了测试,他们给了我相同的结果。我很奇怪为什么我们需要创建一个新的 Animal 对象并将其分配给 Dog.prototype。

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()

【问题讨论】:

标签: javascript inheritance prototype prototypal-inheritance


【解决方案1】:

在这种特殊情况下,您可以出于简单的原因替换这些行:

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

在这里,您使用call 调用Animal 的构造函数,并提供this 从而手动建立Animal 的上下文。因此,function Animal 中的this 将始终引用Dog 的对象。这就是为什么 new 根本不会产生影响的原因。

严格来说,您实际上并没有进行适当的原型继承。您可以通过以下方式确认:

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

这实际上称为constructor stealing,其中Dog 窃取Animal 的构造函数。 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

如您所见,原型继承通常用于对象字面量(想想 Angular 的作用域对象)。

【讨论】:

  • 那么在不窃取构造函数的情况下编写 Dog() 构造函数的正确方法是什么?
  • 我不确定你的第一行。你是说Dog.prototype = new Animal();Dog.prototype = Animal.prototype 都可以吗?甚至,他们做同样的事情?
  • 我从未听说过“构造函数窃取”这个词。鉴于Dog 应该从Animal 继承,它只是一个super 调用
  • @Bergi 我只是说替换该行的最终结果将是相同的(几乎)。我认为这个词并不常见,但它写在我读过的几本书中。 OP检查编辑。
猜你喜欢
  • 2019-01-24
  • 2020-12-28
  • 2016-11-19
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 2018-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多