最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Why can't I inherit the prototype of the Animal class in my javascript code? - Stack Overflow

programmeradmin1浏览0评论

I am trying to create a new class Dog that inherits via prototypical inheritance from the Animal class:

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

However, I get a Javascript error: Uncaught TypeError: Object #<Dog> has no method 'say'.

Why? Shouldn't the Dog object retain an Animal object as a prototype?

I am trying to create a new class Dog that inherits via prototypical inheritance from the Animal class:

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

However, I get a Javascript error: Uncaught TypeError: Object #<Dog> has no method 'say'.

Why? Shouldn't the Dog object retain an Animal object as a prototype?

Share Improve this question asked Jun 30, 2012 at 1:25 John HoffmanJohn Hoffman 18.7k21 gold badges60 silver badges84 bronze badges 3
  • Are you sure you pasted the right code? The word say doesn't appear there once. – Ned Batchelder Commented Jun 30, 2012 at 1:28
  • Because there are no classes? ;) But the issue is that this is already the wrong object at that time (as well as the [[prototype]] being too late for new to utilize). – user166390 Commented Jun 30, 2012 at 1:32
  • 2 BTW, use console.log instead of document.write and alert. It will make your life so much easier in the long run. – hugomg Commented Jun 30, 2012 at 1:37
Add a ment  | 

3 Answers 3

Reset to default 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();

now dog has all of the properties of animal.

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...

The mistake you're making is that 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.

The prototype property is only magical on function objects. 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. The prototype name isn't special in any other context.

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

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:

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 remend 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.

发布评论

评论列表(0)

  1. 暂无评论