Why we will use Prototypes in javascript

What is the different between these 2 snippets of code:

function animal(){
    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
    }
}

function animal(){
    this.name = 'rover';
}
animal.prototype.set_name = function(name){
    this.name = name;
}

They both do the same thing, so whats the difference?

 

Using the prototype makes for faster object creation, since that function does not have to be re-created each time a new object is created.

When you do this:

function animal(){
    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
    }
}

The set_name function is created de novo each and every time you create an animal. But when you do this

animal.prototype.set_name = function(name){
    this.name = name;
}

The function does not have to be re-created each time; it exists in one place in the prototype. So when you call someAnimal.set_name("Ubu"); the this context will be set to someAnimal and (the one and only) set_name function will be called.


There is one advantage to using the first syntax though: functions created in this manner will have access to private data:

function animal(){
    var privateData = 'foo'

    this.name = 'rover';
    this.set_name = function(name){
         this.name = name;
         alert(privateData); //will alert 'foo'
    }
}

Douglas Crockford calls functions created like this “privileged” for that reason: they have access to both public, and private data.

Advertisements

Prototypes in JavaScript

When you define a function within JavaScript, it comes with a few pre-defined properties; one of these is the illusive prototype. In this article, I’ll detail what it is, and why you should use it in your projects.

The prototype property is initially an empty object, and can have members added to it – as you would any other object.

Say, for instance, that we are developing a canvas game and need several (possibly hundreds of) objects on the screen at once. Each object requires its own properties, such as x and y coordinates, width,height, and many others.

We might do it as follows:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
var GameObject1 = {
    x: Math.floor((Math.random() * myCanvasWidth) + 1),
    y: Math.floor((Math.random() * myCanvasHeight) + 1),
    width: 10,
    height: 10,
    draw: function(){
        myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
    }
   ...
};
var GameObject2 = {
    x: Math.floor((Math.random() * myCanvasWidth) + 1),
    y: Math.floor((Math.random() * myCanvasHeight) + 1),
    width: 10,
    height: 10,
    draw: function(){
        myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
    }
    ...
};

… do this 98 more times …

What this will do is create all these objects within memory – all with separate definitions for methods, such as draw and whatever other methods may be required. This is certainly not ideal, as the game will bloat the browsers allocated JavaScript memory, and make it run very slowly… or even stop responding.

While this probably wouldn’t happen with only 100 objects, it still can serve to be quite a performance hit, as it will need to look up one hundred different objects, rather than just the single prototype object.

To make the application run faster (and follow best practices), we can (re)define the prototype property of the GameObject; every instance of GameObject will then reference the methods within GameObject.prototype as if they were their own methods.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
// define the GameObject constructor function
var GameObject = function(width, height) {
    this.x = Math.floor((Math.random() * myCanvasWidth) + 1);
    this.y = Math.floor((Math.random() * myCanvasHeight) + 1);
    this.width = width;
    this.height = height;
    return this;
};
// (re)define the GameObject prototype object
GameObject.prototype = {
    x: 0,
    y: 0,
    width: 5,
    width: 5,
    draw: function() {
        myCanvasContext.fillRect(this.x, this.y, this.width, this.height);
    }
};

We can then instantiate the GameObject 100 times.

1
2
3
4
5
6
var x = 100,
arrayOfGameObjects = [];
do {
    arrayOfGameObjects.push(new GameObject(10, 10));
} while(x--);

Now we have an array of 100 GameObjects, which all share the same prototype and definition of the draw method, which drastically saves memory within the application.

When we call the draw method, it will reference the exact same function.

1
2
3
4
5
var GameLoop = function() {
    for(gameObject in arrayOfGameObjects) {
        gameObject.draw();
    }
};

An object’s prototype is a live object, so to speak. This simply means that, if, after we create all our GameObject instances, we decide that, instead of drawing a rectangle, we want to draw a circle, we can update our GameObject.prototype.draw method accordingly.

1
2
3
GameObject.prototype.draw = function() {
    myCanvasContext.arc(this.x, this.y, this.width, 0, Math.PI*2, true);
}

And now, all the previous instances of GameObject and any future instances will draw a circle.

Hopefully, this article has shed some light on the backbone of JavaScript that is prototype. You should now be on your way to creating more efficient applications.

Source: http://code.tutsplus.com/tutorials/prototypes-in-javascript–net-24949