Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reason for using .prototype in Javascript

What are the technical reasons for using .prototype instead of declaring functions and members inside the object itself. It is easiest to explain with code examples.

What are the advantages of using:

RobsObject = function(data){
    this.instanceID = data.instanceID;
    this._formButton = document.getElementById('formSubmit_' + this.instanceID);
    if(this._formButton)
    {
        //set a click listener that
        //points to this._onSubmit, this._onSuccess, and this.onFailure
    }
};

RobsObject.prototype = {
    _onSubmit: function(type, args)
    {
        //make an ajax call
    },

    _onSuccess: function(type, args)
    {
        //display data on the page
    },

    _onFailure: function(type, args)
    {
        //show an alert of some kind
    },
};

As oppose to declaring your functions inside of the Object like:

RobsObject = function(data){
    this.instanceID = data.instanceID;
    this._formButton = document.getElementById('formSubmit_' + this.instanceID);
    if(this._formButton)
    {
        //set a click listener that
        //points to this._onSubmit, this._onSuccess, and this.onFailure
    }

    this._onSubmit = function(type, args)
    {
        //make an ajax call
    }

    this._onSuccess = function(type, args)
    {
        //display data on the page
    }

    this._onFailure = function(type, args)
    {
        //show an alert of some kind
    }
};

Thanks.

Edit: As many of you have pointed out my functions in the second code snippet should have 'this' in front of them in order to be public. So I added it. Just a mistake on my part.

like image 499
Rob Lund Avatar asked Dec 04 '22 13:12

Rob Lund


2 Answers

Everything declared in a constructor function's prototype is shared by all instances of that constructor function. If you define functions in the constructor function, then each instance gets its own copy of the function, which wastes memory (and could potentially cause problems if you compare properties between two instances later).

Also, in your example the functions declared in the constructor function are private to the scope of the function. They cannot be called as member methods on instances. For that you would need to assign them to properties of the object:

MyObject = functon() {
  // ...

  this.myMethod = function() {
    // ...
  };
}

Douglas Crockford has a good write-up of prototypical inheritance that is definitely worth checking out: Prototypical Inheritance in JavaScript.

UPDATE: Brief Prototype Summary

When you create a new object using a constructor function, the value of the function's prototype property is assigned as the new object's prototype object. (Yes, the names are confusing!) This is a lot like assigning a superclass in a class-based language (but not quite! Read Crockford's page!)

// MyObject constructor function:
MyObject = function() {
  this.a = 1;
}

// Define an object to use as a prototype.
var thePrototype = { b: 2 };

// Assign thePrototype as the prototype object for new instances of MyObject.
MyObject.prototype = thePrototype;

// Create an instance of MyObject.
var x = new MyObject();
// Everything in thePrototype is available to x.
console.log(x.b);

// x's prototype is a reference to thePrototype, so updating it affects x.
thePrototype.c = 3;
console.log(x.c);

// Setting properties on x always sets them *on x*, even if the property is
//  defined on the prototype:
x.b = 0;
y = new MyObject();
console.log(x.b);
console.log(y.b);
like image 176
Annabelle Avatar answered Feb 09 '23 11:02

Annabelle


The answer is memory. If you put the members inside of the object itself, then EVERY instance of that object will contain (in memory) all members. If you use prototype, on the other hand, it only exists once, and all instances will access those members as if they were their own.

like image 39
Gabriel McAdams Avatar answered Feb 09 '23 12:02

Gabriel McAdams