Reputation: 125
A closure is the combination of a function and the lexical environment within which that function was declared.
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?
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?
Clarification on this would be great.
Upvotes: 0
Views: 88
Reputation: 664444
Your understanding is correct.
Thus, here, is it implying that
counter1
andcounter2
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