3

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");
}
Community
  • 1
  • 1
nuway
  • 2,142
  • 3
  • 23
  • 47

3 Answers3

3

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.

Matt Greer
  • 57,161
  • 16
  • 118
  • 122
  • 1
    @nuway: Try not to think of it too much in classical terms; it'll drive you crazy when the illusion breaks. JS doesn't have classes, and thus doesn't have `static`. In JS, you have prototypes (which are just regular objects), and other objects inherit directly from the prototype rather than its class. That is, *the prototype is an instance*. Stuff on the prototype is inherited by everything that inherits from the prototype...but it's not "static", as any function in the prototype can still work on `this` and do the right thing. – cHao Aug 03 '12 at 21:39
  • What's more, the "static" stuff can be overridden at will without breaking sibling objects. If there's an `x` on your prototype with a value of '1', and you say `this.x = 0;`, you get your own `x` -- that looks just like the prototype's version (except for the different value, of course, and `you.hasOwnProperty('x')` returning `true`) to any function that messes with you, even functions in the prototype. – cHao Aug 03 '12 at 21:57
2

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/

Marcelo De Zen
  • 8,957
  • 3
  • 32
  • 48
1

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.)

Ry-
  • 199,309
  • 51
  • 404
  • 420