151SoBad
151SoBad

Reputation: 125

Javascript Closures and terminology

Firstly, taking note of MDN's definition of a closure:

A closure is the combination of a function and the lexical environment within which that function was declared.

In the below code, a singleton is produced as a result of the IIFE.

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

console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1

It is then said that "those three public functions (increment, decrement, and value) are closures that share the same lexical environment".

In other words, if I interpret that correctly: The following methods/functions: increment, decrement and value, are each, in themselves, closures?

Taking a look at the next code, where there is not an IIFE, but a function factory:

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 */

"Each of the counters, counter1 and counter2, maintains its independence from the other. Each closure references a different version of the privateCounter variable through its own closure."

Thus, here, is it implying that counter1 and counter2 are each closures? If so, that wouldn't be consistent with the definition provided at the top here of what a 'closure' is?

So in the first code (featuring an IIFE), MDN is saying that each of the inner functions that are being returned are the closures. However, in the 2nd code (featuring a function factory), MDN appears to be saying it is the variables that are referencing the returned object (which contains the 3 methods or function properties: increment, decrement and value), that are closures?

Ultimately, obviously regardless of whether it's an IIFE or a function factory doesn't affect the definition of a 'closure', but the comments made on the page has not allowed me to gain clarity on what actually is the closure(s) here?

Per the MDN definition of a closure above, what I think the closures are:

In the 1st code, the increment, decrement and value functions are each closures that are formed (where all 3 are sharing the same lexical environment - and hence sharing the same closure variable - 'privateCounter').

In the 2nd code, the increment, decrement and value functions are each closures that are formed (where all 3 are sharing the same lexical environment - and hence sharing the same closure variable - 'privateCounter'). BUT, as a result of makeCounter() being called twice, with its return value set to two different variables, there would be two sets of those 3 closures formed (i.e. 6 closures, if you like), each set sharing the same lexical environment (the privateCounter variable).

That's what I understand from the MDN definition, but I have doubts about what the closures actually are in the 2nd code. Surely it's more understandable to say there are only 2 closures in the 2nd code? But in saying that, aren't you implying that the object being returned is a closure, and arguably, objects cannot form or be part of a closure?

tl;dr: What IS(are) the closure(s) in both these two sets of code?

Clarification on this would be great.

Upvotes: 0

Views: 88

Answers (1)

Bergi
Bergi

Reputation: 664444

Your understanding is correct.

Thus, here, is it implying that counter1 and counter2 are each closures?

No. It's referring to their methods. As you said, a closure is always a function.

We could reformulate the sentence as "Each of the counters, counter1 and counter2, maintains its independence from the other. The closures on each object reference a different version of the privateCounter variable through its own closure."

(However, the last word "closure" here doesn't refer to the function, it's just the substantive for the act of closing [over the lexical environment]).

Is there anything inaccurate or incorrect with the above statements?

They're both fine. The only thing I'd mention is that in "sharing the same closure variable - privateCounter" you forgot about the changeBy variable that is in the same scope and shared with it.

Upvotes: 1

Related Questions