简体   繁体   English

为什么我不能在我的javascript代码中继承Animal类的原型?

[英]Why can't I inherit the prototype of the Animal class in my javascript code?

I am trying to create a new class Dog that inherits via prototypical inheritance from the Animal class: 我正在尝试创建一个新的类Dog ,它继承自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 JS小提琴

However, I get a Javascript error: Uncaught TypeError: Object #<Dog> has no method 'say' . 但是,我收到一个Javascript错误: Uncaught TypeError: Object #<Dog> has no method 'say'

Why? 为什么? Shouldn't the Dog object retain an Animal object as a prototype? Dog对象不应该将Animal对象保留为原型吗?

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

now dog has all of the properties of animal. 现在狗拥有动物的所有属性。

jsfiddle 的jsfiddle

@ryan's answer is correct, of course, but he doesn't really say what's different about it and it might not be clear to a beginner, so... 当然,@ ryan的回答是正确的,但他并没有真正说出它的不同之处,对初学者来说可能并不清楚,所以...

The mistake you're making is that this.prototype = new Animal(); 你犯的错误是this.prototype = new Animal(); assigns an Animal instance to a property named prototype on the current Dog instance (referred to by this ), but there's nothing special about a property named prototype in this context. 将一个Animal实例分配给当前Dog 实例上的一个名为prototype的属性( this引用),但在此上下文中没有关于名为prototype的属性的特殊内容。

The prototype property is only magical on function objects. prototype属性在函数对象上只是神奇的。 When you create a new instance of SomeFunc using new SomeFunc() that new object's internal/hidden [[prototype]] pointer will refer to the object pointed to by SomeFunc.prototype . 当您使用new SomeFunc()创建SomeFunc的新实例时,新对象的内部/隐藏[[prototype]]指针将引用SomeFunc.prototype指向的对象。 The prototype name isn't special in any other context. prototype名称在任何其他上下文中都不是特殊的。

The "prototype" property is just a regular property. “原型”属性只是一个常规属性。 The real [[Proto]] property that deals with delegation is hidden and can't be directly manipulated after an object is created (except with some extensions: in Firefox, its the __proto__ property). 处理委托的真实[[Proto]]属性是隐藏的,在创建对象后无法直接操作(除了一些扩展:在Firefox中,它的__proto__属性)。

A correct Javascript inheritance example that is similar in spirit to what you are doing would use Object.create to create a dog with the correct [[Prototype]] property: 正确的Javascript继承示例与您正在进行的操作类似,将使用Object.create创建具有正确[[Prototype]]属性的狗:

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

A more idiomatic example would be something like ryan's answer, although I would recommend using Object.create instead of new Animal to instantiate the dog prototype and I would put the animal methods in a separate animal prototype instead of manually attaching them in the constructor like you are doing. 一个更惯用的例子就像ryan的答案,虽然我建议使用Object.create而不是new Animal来实例化狗原型,我会将动物方法放在一个单独的动物原型中,而不是像你一样手动将它们附加在构造函数中是做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM