Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantages of using prototype, vs defining methods straight in the constructor? [duplicate]

I am wondering if there are any advantages of using any of these over the other, and which way should I go?

Constructor approach:

var Class = function () {      this.calc = function (a, b) {         return a + b;     };  }; 

Prototype approach:

var Class = function () {};  Class.prototype.calc = function (a, b) {     return a + b; }; 

I don't like that, using the prototype, method definitions are separated from the class, and I'm not aware if there is any specific reason I should use this over just the first approach.

Also, is there any benefit of using a function literal to define a "class", over just function definition:

var Class = function () {}; 

vs

function Class () {}; 

Thanks!

like image 379
Leo Avatar asked Dec 22 '10 10:12

Leo


People also ask

What are the advantages of prototype in JavaScript?

Prototypes allow you to easily define methods to all instances of a particular object. The beauty is that the method is applied to the prototype, so it is only stored in the memory once, but every instance of the object has access to it. Let's use the Pet object that we created in the previous post.

What is the difference between constructor and prototype?

So what's the difference between constructor and prototype? A short answer is that the constructor is a function that is used to create an object, while the prototype is an object that contains properties and methods that are inherited by objects created from a constructor.

Why are prototypes more efficient than other techniques for creating classes in JavaScript?

There is a clear reason why you should use prototypes when creating classes in JavaScript. They use less memory. When a method is defined using this. methodName a new copy is created every time a new object is instantiated.

What is the difference between adding a method inside the constructor and adding it to the prototype?

One big difference is that methods/properties added via prototype are only stored once (objects “containing” the prototype just “reference” the method/property) whereas methods/properties added in the constructor are parsed and copied for each instance created by that constructor.


1 Answers

Methods that inherit via the prototype chain can be changed universally for all instances, for example:

function Class () {} Class.prototype.calc = function (a, b) {     return a + b; }  // Create 2 instances: var ins1 = new Class(),     ins2 = new Class();  // Test the calc method: console.log(ins1.calc(1,1), ins2.calc(1,1)); // -> 2, 2  // Change the prototype method Class.prototype.calc = function () {     var args = Array.prototype.slice.apply(arguments),         res = 0, c;      while (c = args.shift())         res += c;      return res;  }  // Test the calc method: console.log(ins1.calc(1,1,1), ins2.calc(1,1,1)); // -> 3, 3 

Notice how changing the method applied to both instances? This is because ins1 and ins2 share the same calc() function. In order to do this with public methods created during construction, you'd have to assign the new method to each instance that has been created, which is an awkward task. This is because ins1 and ins2 would have their own, individually created calc() functions.

Another side effect of creating methods inside the constructor is poorer performance. Each method has to be created every time the constructor function runs. Methods on the prototype chain are created once and then "inherited" by each instance. On the flip side of the coin, public methods have access to "private" variables, which isn't possible with inherited methods.

As for your function Class() {} vs var Class = function () {} question, the former is "hoisted" to the top of the current scope before execution. For the latter, the variable declaration is hoisted, but not the assignment. For example:

// Error, fn is called before the function is assigned! fn(); var fn = function () { alert("test!"); }   // Works as expected: the fn2 declaration is hoisted above the call fn2(); function fn2() { alert("test!"); } 
like image 187
Andy E Avatar answered Sep 21 '22 12:09

Andy E