Question

Possible Duplicate:
Javascript - this Vs. prototype
Advantages of using prototype, vs defining methods straight in the constructor?
Prototype or inline, what is the difference?

When creating a class in JavaScript, how is declaring methods inside the object using this different then declaring it by accessing the prototype ? it seems to me to serve the same purpose.

window.onload = function() { 
    tc = new TestClass();
    tc.init(); //logs initting
    tc.reset(); //logs resetting
    tc.doSomething(); //logs doing something
};


var TestClass = function(){

    this.init = function(){
        console.log("initting");
    }

    this.reset = function(){
        console.log("resetting");
    }

    this.destroy = function(){
        console.log("destroying");
    }

}

TestClass.prototype.doSomething = function(){

    console.log("doing something");
}
Was it helpful?

Solution

In most situations you will have the same functional result. But internally it's quite different in that when you attach the functions to this, then every instance of the type gets its own copy of the function. By attaching the functions to prototype, all instances share the same function instances. Using prototype reduces memory usage.

OTHER TIPS

Before you read: English is not my mother language ;)

In practice both this and prototype is almost the same, but this and prototype has distinct meaning in javascript.

1) Javascript is based on prototype inheritance. What this mean is that one object can inherit the prototype model from another object. Using prototype you can emulate inheritance on javacript (with limitations), for example:

// create a 'class' Vehicle
var Vehicle = function() {};
Vehicle.prototype.wheels = 0;
Vehicle.prototype.maxSpeed = 0;
Vehicle.prototype.displayInfo = function() { 
     alert("hello, I have " + this.wheels + " wheels and max speed of " + this.maxSpeed);
};

var vehicleInstance = new Vehicle();
vehicleInstance.displayInfo(); // displays: Hello, I have 0 wheels and max speed of 0

// create a 'class' Car using the prototype from Vehicle 
// and change some properties.
var Car = function(maxSpeed) { 
    if(maxSpeed)
      this.maxSpeed = maxSpeed;
};
// inherit the prototype from vehicle
Car.prototype = new Vehicle();  
// change some properties
Car.prototype.maxSpeed = 200;
Car.prototype.wheels = 4;

var car = new Car();
car.displayInfo(); // displays: Hello, I have 4 wheels and max speed of 200

2) Properties in this has precedence over properties in prototype, for example:

var car = new Car(); // car prototype: maxSpeed = 200;
car.displayInfo() // displays: Hello, I have 4 wheels and max speed of 200

//set maxSpeed to 300 on 'this'
var car = new Car(300); // see Car definition above

// call displayInfo() in car instance. The Car 'class' doesn't have displayInfo()
// itself, but its prototype has. The javascript VM will look
// for displayInfo() in the car instance, if it not found in the
// instance it will look in car.prototype and on car.prototype.prototype etc.
// until it founds a property called displayInfo() 
// or reaches the end of the chain (Object.prototype).
car.displayInfo() // displays: Hello, I have 4 wheels and max speed of 300

This also applies for the prototype of the prototype, for example.

var Class1 = function() { };
Class1.prototype.someValue = 1;

var Class2 = function() { };
Class2.prototype = new Class1();
Class2.prototype.someValue = 2; // this overrides the Class1.prototype.someValue prototype

var class2 = new Class2();
class2.someValue = 3; // this overrides the Class2.prototype.someValue;

3) Properties defined on prototype are not instantiated for every new instance of the same object, for example:

// create a new class and inherit the prototype model from Vehicle.
var Motorcycle = function() { };
Motorcycle.prototype = new Vehicle();
// motorcycles has 2 wheels
Motorcycle.prototype.wheels = 2;

var motorcycle = new Motorcycle();
motorcycle.dysplayInfo(); // displays: Hello, I have 2 wheels and max speed of 200

//now, if I change the method dysplayInfo from Vehicle, it will change for every
//object that inherits Vehicle prototype:
Vehicle.prototype.displayInfo = function() { 
    Alert("Wheels: " + this.wheels + ", Max speed: " + this.maxSpeed);
}

//observe that I didn't create another Motorcycle instance ,
//I'm using the same instance that I've created before change
//the Vehicle.dysplayInfo() method
motorcycle.displayInfo() // displays: Wheels: 2, Max speed: 200

As you can see, the same method used in Vehicle is used by any object that inherits his prototype. This make your code much more efficient, since you're using the same function for more than one object. You can have thousands of objects inheriting from a fat prototype and still get a low memory footprint.

In short: By using prototype you are able to create powerful 'classes like' objects, with a well defined inheritance tree (we say prototype chain) which will run more efficiently and will use less memory.

What I have said here does not exhaust the subject of prototype inheritance/chain. Here are other resources you can read. I recommend since understand prototypes in javascript is essencial to write good and maintainable code.

What I have said here does not exhaust the subject of prototypes: https://developer.mozilla.org/en-US/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript?redirectlocale=en-US&redirectslug=Introduction_to_Object-Oriented_JavaScript

http://javascript.crockford.com/prototypal.html

http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/

They have the same effect in that particular case, but they're very different. One (the?) major difference is that methods attached using this are properties of the object itself and not of its prototype, so iterating the object like so:

for(var x in tc) {
    if(tc.hasOwnProperty(x)) {
        console.log('Has property ' + x);
    }
}

will omit methods added using prototype. Another difference is the references; assigning the methods to this will create new function objects each time, but using the prototype, they're all the same function. (This may or may not be what you want, and it matters most when attaching extra properties to the methods.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top