I'm studying closures and revealing module pattern. It seemed to me I got it, but then during practice i found this strange "bug". Here's the code:
const module=(function(){
let counter=1;
let incrCounter=function(){
counter++;
console.log(counter)
}
return { counter, incrCounter}
})();
module.incrCounter(); ///expected:2; output:2;
module.incrCounter(); ///expected:3; output:3
module.incrCounter(); ///expected:4 output:4
module.counter=1;
module.incrCounter(); ///expected:2; output:5
module.counter; ///expected:5 (for some reason) ; output:1
I reread "You don't know JS" about closures. It has to work! I return an object with property "counter", so I should have the direct access to it. But it seems that i creating a new, local variable with the same name, and not updating the counter I want to. What am I doing wrong here?
When you do return {counter, incrCounter}
, you are saying:
counter
into the counter
property of the return objectincrCounter
into the incrCounter
property of the return objectYou are not saying to expose the internal counter variable, which means modifications to module.counter
simply modify the copy, not the actual value. You can fix this by storing it in an object:
const module = (function() {
let ret = {counter: 1};
let incrCounter = function() {
ret.counter ++;
console.log(ret.counter);
};
ret.incrCounter = incrCounter;
return ret;
})();
Or, just using objects and this
:
const module = {
counter: 1,
incrCounter() {
this.counter ++;
console.log(this.counter);
}
};