1

I was reading Closures and it has the example of the following closure.

var makeCounter = function() {
var privateCounter = 0;
  function changeBy(val) 
     {
       privateCounter += val;
     }
  return 
     {
       increment: function() 
     {
       changeBy(1);
     },
  decrement: function() 
     {
       changeBy(-1);
     },
  value: function() 
     {
       return privateCounter;
     }
   }
};

var counter1 = makeCounter();
var counter2 = makeCounter();
alert(counter1.value()); /* Alerts 0 */
counter1.increment();
counter1.increment();
alert(counter1.value()); /* Alerts 2 */
counter1.decrement();
alert(counter1.value()); /* Alerts 1 */
alert(counter2.value()); /* Alerts 0 */

I was wondering what the difference and advantages/disadvantages are between this closure and the following code that produce the same results.

var makeCounter = function() {
var privateCounter = 0;
  function changeBy(val) 
      {
        privateCounter += val;
      };
   this.increment= function() 
     {
       changeBy(1);
     };
   this.decrement= function()
     {
       changeBy(-1);
     };
   this.value= function() 
     {
       return privateCounter;
     };
  };

var counter1 = new makeCounter();
var counter2 = new makeCounter();
alert(counter1.value()); /* Alerts 0 */
counter1.increment();
counter1.increment();
alert(counter1.value()); /* Alerts 2 */
counter1.decrement();
alert(counter1.value()); /* Alerts 1 */
alert(counter2.value()); /* Alerts 0 */
1
  • Select your code, hit the {} button in the toolbar to indent it by 4 spaces. That's how you mark code as code here. Read the rest of the editing help while you're at it. It'd do it for you, but I'm not going to clean all those <br>s out. Commented Apr 9, 2015 at 13:02

1 Answer 1

1

Your second version does use closures as well, there's hardly a difference in that regard.

The important difference is that your first makeCounter is a factory that returns an object literal (which inherits from Object.prototype), while your second makeCounter is a constructor function (needs to be called with new) that does return an instance which inherits from makeCounter.prototype. You could gain some advantages by moving your methods on the prototype:

function Counter() {
    var privateCounter = 0;
    this.changeBy = function changeBy(val) {
        privateCounter += val;
    };
    this.value = function() {
        return privateCounter;
    };
}
Counter.prototype.increment = function() {
    this.changeBy(1);
};
Counter.prototype.decrement = function() {
    this.changeBy(-1);
};

You could avoid the closures (privileged methods) and use prototype methods only:

function Counter() {
    this.counter = 0; // no more private
}
Counter.prototype.valueOf = function() {
    return this.ounter;
};
Counter.prototype.increment = function() {
    this.counter += 1;
};
Counter.prototype.decrement = function() {
    this.counter -= 1;
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.