user1365697
user1365697

Reputation: 5989

Meaning of prototype in javascript

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

Answers (7)

Ravi Verma
Ravi Verma

Reputation: 74

First of all understand few concepts before looking at javascript prototypes:

  1. Constructors: So basically in javascript any function that is called with a new keyword acts as a constructor and will return an object.
  2. 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

Raj Mishra
Raj Mishra

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

Linus Thiel
Linus Thiel

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

Hasith
Hasith

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

Christoph
Christoph

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

Joseph
Joseph

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

hvgotcodes
hvgotcodes

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

Related Questions