Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constructor vs. closure?

What exactly is different about these 2 objects, a created using a constructor, b using a closure?

Is the property __proto__ useful for anything that cannot be achieved by using a closure? Am I supposed to use these techniques in different situations? Is there a difference in memory usage?

(jsFiddle)

window.MODULE = {};

MODULE.constructor = function(){
        this.publicVariable = 10;
};
MODULE.constructor.prototype.publicMethod = function(){
    return this.publicVariable;
};
//-------------------------------//
MODULE.closure = (function(){
    var publicMethod = function(){
        return this.publicVariable;
    };
    return function(){
        var obj = {};
        obj.publicVariable = 10;
        obj.publicMethod = publicMethod;
        return obj;
    };
}());
//-------------------------------//
var a = new MODULE.constructor();
console.log("constructor", a.publicMethod(), a)
var b = MODULE.closure();
console.log("closure", b.publicMethod(), b)

Also see a more complicated jsFiddle comparison with some private and static properties - both techniques work the same as far as I can tell...

like image 424
Aprillion Avatar asked Sep 19 '13 18:09

Aprillion


1 Answers

Roughly, the main advantages of prototypal inheritance (your "constructor" method) are makes it easier to do subclasses and monkeypatching (adding methods to an existing class) while closures are nice if you want private instance variables and methods ("protected methods" are still hard to do with either method) or prefer lexical scoping instead of dynamic scoping with "this" (useful if someone does setTimeout(obj.method, 1000))

As for performance, prototypal inheritance can be a bit more efficient because implementations are tuned to it but it really shouldn't matter unless you instantiate lots of objects from that class.


Private variable example:

var counter  = function(){
   var count = 0; //private variable

   var increment = function(){ // private method
      count ++;
   };

   return { //public interface
      next: function(){
         increment();
         return count;
      },
   }
}

var c = counter();
console.log(c.next());
console.log(c.next());
like image 159
hugomg Avatar answered Oct 05 '22 17:10

hugomg