Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Prototype explanation needed

I normally in my project create my class in this way... Object literal.

var objectName = {

     //global variables
      a : 'somevalue',

      func1: function(){

      },


      func2: function(){

      }

}

If i have to turn this into prototype format, how would I do that?

What would be my advantage of using prototype than this one, when the job is getting done with this format.

Why do people speak so much on prototype.

like image 285
John Cooper Avatar asked Aug 23 '11 11:08

John Cooper


1 Answers

Turned into a prototype would look something like:

var someObject = function() {
    this.a = "somevalue";
};

someObject.prototype.func1 = function() { // work };
someObject.prototype.func2 = function() { // work };

var myObject = new someObject();

What are some advantages? Well, there are a bunch, but there are a handful really practical reasons when prototypes make more sense than object literals.

First is reduction of duplicated code; So, lets say you wanted another object very smiliar to objectName, but you wanted a to be a different value. You would probably end up with something like:

var objectName = {
      a : 'somevalue',
      func1: function(){ },
      func2: function(){ }
}

var otherObjectName = {
      a : 'otherValue',
      func1: function(){ },
      func2: function(){ }
}

And you could reduce the duplicated functions by saying

var objectName = {
      a : 'somevalue',
      func1: function(){ },
      func2: function(){ }
}

var otherObjectName = {
      a : 'otherValue',
      func1: objectName.func1,
      func2: objectName.func2
}

Or, using a prototype, I could just make it so I could pass in the value I want for a in during the construction of the object. The refactored code would look something like this:

var someObject = function(a) {
    this.a = a;
};

someObject.prototype.func1 = function() { /* work */ };
someObject.prototype.func2 = function() { /* work */ };

var myObject = new someObject("somevalue");
var myOtherObject = new someObject("otherValue");

Now, if i wanted to add a new function to both of them. Using the object literal apporach, then you would have to remember to also add it to otherObjectName. As the number of your literals increased, it would take longer and more difficult to manage them all.

Using the prototype approach, all we would have to say is:

someObject.prototype.func3 = function() { // do even more work }

or even more interesting i could dynamically extend both object by only having a reference to one by saying.

// find what function made me, get its prototype, and add a new function to it
myObject.constructor.prototype.func3 = function() { /* work */ }
myOtherObject.func3() // tada magic!

or I could make a new object, by only knowing a reference. like:

var newObject = myObject.constructor(myObject.a + " new");

Because both myObject and myOtherObject share the same constructor and prototype, there are a lot of interesting things you can do with that relationship that you can't do with object literals.

You can think of prototypes as little factories to create objects rather than having to create every object yourself as a literal.

Now, if you are thinking, "Well, I'm only going to have one of these and I'm not going to be doing any of your crazy method extending magic." Then defining an object literals is a perfectly valid apporach for some problems. Sometimes using a prototype is better. Use the pattern that makes sense for the problem that you are trying to solve, rather than trying to fit your problem into a pattern.

like image 197
J. Holmes Avatar answered Nov 08 '22 18:11

J. Holmes