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?
-
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 fornew
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
3 Answers
Reset to default 7function 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.