Reputation: 5989
I wrote short code of inheritance of reader
from Person
:
<script>
/* Class Person. */
function Person(name) {
this.name = name;
}
Person.prototype.getName = function() {
return this.name;
}
var reader = new Person('John Smith');
alert(reader.getName());
</script>
Alternatively I can delete the line of Person.prototype.getName = function() { return this.name; }
and create it in the Person object. For example
<script>
/* Class Person. */
function Person(name) {
this.name = name;
this.getName = function() { return this.name;}
}
var reader = new Person('John Smith');
alert(reader.getName());
</script>
I got the same result when invoking getName()
in both these cases. So how are they different?
Upvotes: 20
Views: 5042
Reputation: 74
First of all understand few concepts before looking at javascript prototypes:
this
keyword inside the constructor: So when you use this
keyword inside a function and then call that function with a new
keyword. That this
keyword is implicitly binded with that returned object and if you assign any property or method to this
keyword, it will be assigned to that returned object. As shown in code sample provided below:function foo(){
this.name="foo"
this.greet=function(){
console.log("Good morning")
}
}
const obj=new foo()
So now if you want to have some property that will stay the same for all objects created, Then it doesn't make sense to assign that property or method separate memory for each object instance. Rather you can define it on the prototype property of the constructor and then it will be accessible to all the objects created using that constructor. For example in sample given above greet method will stay same for all objects , So we can refactor as shown below:
function foo(){
this.name="foo"
}
foo.prototype.greet=function(){
console.log("Good morning")
}
const obj=new foo()
It's not inheritance!!!
Some people might depict it as an inheritance. But don't get confused, It's not your classical inheritance. But instead, it is delegation. So in the above code sample when you try to call the greet
method w.r.t to obj
. Interpreter says he can't find it. So he will look at to which prototype this object is pointing. It will be pointing to the foo
function's prototype. So it will look into it and will find greet
method defined there.
Upvotes: 0
Reputation: 1
When you add any function with this.functionname
to any object constructor every object created by that constructor makes their own copy of that function which also takes memory. Imagine if you have several objects created by same constructor and how much memory it will take. on other hand when you creates it with cunstructorName.prototype.functionName
function loads only once in memory and every object shares same prototype function constructor. this approach makes your code faster in loading and operation and also saves a big chunk of memory.
Upvotes: 0
Reputation: 39223
The difference is that when you put it on the prototype, all instances of Person
share the same code for getName
-- you can change getName
on all instances of Person
by assigning something else:
Person.prototype.getName = function() { return 'Mr Jones' };
Also, since they share the same code, it's less memory intensive: You only have one copy of the getName
function, instead of one copy per instance.
Another difference is that you can later set the Person
as the prototype of another class, let's say Man
, and it will inherit the properties/methods.
Update: Here is a good post explaining other properties of prototypes: https://stackoverflow.com/a/1534286/295262
Upvotes: 3
Reputation: 1767
The difference is that is you further extend the Person class the sub classes will not inherit the getName() method
Edit: I was not correct in above statement. Just tested on the jsfiddle. Regardless of if we define a method on the prototype or on the function instance itself, it is available for the subclasses in the chain.
Here is the proof: http://jsfiddle.net/u8qrd/
I understand that there is a performance/memory benefit of attaching the methods to prototype. Appart from that isn't there any behavioral difference when it comes to inheritance?
(hopefully I'm not violating SO rules by asking a question here)
Upvotes: 2
Reputation: 51181
In class-based words the difference between declaring a function via prototype
and this
would be something like this:
prototype:
the function of the instance would look like this:
somefunc = function(){super()/*call the function of the super-class*/};
this:
the function of the instance would look like this:
somefunc = function(){/* Do same stuff as in the prototype func declared */};
Now changing the function on the prototype will have no effect on the instance.
Upvotes: 0
Reputation: 119827
When you put the method in the constructor and create an object out of that constructor, each object carries it's own getName
function. For 10 Person
instances, each carries it's own getName
, therefore 10 separate getName
functions.
If you place getName
in the prototype of the constructor, that same getName
function is shared/inherited across all instances. so for 10 instances of Person
, each has getName
but refer only to 1 getName
function.
Using prototypes saves memory since the method is shared across instances so only one is used.
Upvotes: 4
Reputation: 120138
When you put something on the prototype, every instance of the object shares the same code for the method. They are all using the same function instance.
When you simply put a method on this
, every object instance has its own copy of the same method.
Using prototype
is much more efficient. Note this is why typically methods are placed on the prototype, since you typically want all instances to use the same method, but properties are placed on the instance itself, because typically you don't want all instances to share the same properties.
For your comment, if you put a method on the constructor function of an object, then you have in effect created a "static" method. No instance of the object will have that method, they all must access it on the constructor function. So in your case, Person.someMethod()
.
Upvotes: 24