I would like to know what is the difference between overriding methods with prototypes and without prototypes. Consider:
Example 1:
function Animal() {
this.sleep = function () {
alert("animal sleeping");
};
this.eat = function () {
alert("animal eating");
};
}
function Dog() {
this.eat = function () {
alert("Dog eating");
};
}
Dog.prototype = new Animal;
var dog = new Dog;
dog.eat();
Example 2:
function Animal() { }
function Dog() { }
Animal.prototype.sleep = function () {
alert("animal sleeping");
};
Animal.prototype.eat = function () {
alert("animal eating");
};
Dog.prototype = new Animal;
Dog.prototype.eat = function () {
alert("Dog eating");
};
var dog = new Dog;
dog.eat();
I feel both examples produce the same effect that the Dog
class is overriding the eat method of the Animal
class. Or is there anything different happening?
As Arun mentioned in the first example you're creating
sleep
andeat
functions for each new instance. In the second example there's only onesleep
andeat
function which is shared amongst all the instances.In this case the second method is better, but it's good to know when to use the first method and when to use the second. A little bit of theory first:
Note: There are four kinds of variables in JavaScript -
private
,public
,shared
andstatic
.Private variables are inaccessible outside of the function in which they are defined. For example:
Public variables are defined on the
this
object inside a function. For example:Shared variables are shared on the
prototype
of the function. For example:Static variables are properties of the function itself. For example:
Most often it's best to declare the methods of a constructor function as shared methods since all instances of the constructor share them. However if your method needs to access a private variable then it must be declared as a public method itself.
Note: This is my own nomenclature. Not many JavaScript programmers adhere to it. Others seem to follow Douglas Crockford's nomenclature: http://javascript.crockford.com/private.html
To know more about prototypal inheritance in JavaScript read the following answer: https://stackoverflow.com/a/8096017/783743
In the first method each of the
Animal
instance will get its own implementation ofsleep
andeat
methods.While in the second model All instances will share the same instance of the
sleep
andeat
methods.The second model is better since we can share the methods.
In your first example each new
Dog
instance will have it's owneat
method and in the second example there will be only oneeat
method onDog.prototype
, which will be shared between all future instances ofDog
like Arun mentioned.This is the only "tricky" difference between those two. But it's always better to define methods on the
prototype
to avoid high memory consumption and leaks.The methods in first example are defined in object instance.
You're setting the
Dog
prototype to a newAnimal
instance, thusDog
will inheritsleep
andeat
functions fromAnimal
. Then you're DEFINING (NOT OVERRIDING)eat
method inDog
constructor as an instance method, and this will HIDE the inheritedeat
method inDog
instances.Consider the following example:
The code above will alert
animal eating
with your code in first example.And will alert
Dog eating
with the code in the second one.