Reputation: 51
Studying about closures, I looked at the Developer's Mozilla article about it and saw the code below:
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()); // 0.
counter.increment();
counter.increment();
console.log(counter.value()); // 2.
counter.decrement();
console.log(counter.value()); // 1.
I'm confused about how the function is attributed to the variable counter
, because the function is initially envolved by those parentheses, and after all, there are also two unreaseble parentheses together... I just wondered, what's the reason of that syntax? I certainly would do:
var counter = function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
};
};
But then I got the error
Uncaught TypeError: counter.value is not a function
When I do console.log(counter.value());
Can someone please explain it to me?
Upvotes: 1
Views: 45
Reputation: 84922
What you're looking at is an Immediately Invoked Function Expression or IIFE. This code is creating a function, then immediately calling that function, then assigning the return value of the function to counter
. So counter
isn't a function, it's an object with three properties: increment
, decrement
, and value
.
The reason that they used an IIFE was to make what's essentially a private variable. privateCounter
is only in scope to other code inside that function, which means only increment
, decrement
, and value
can access it.
If they didn't care about making the variable private, the equivalent code would be:
var publicCounter = 0;
function changeBy(val) {
publicCounter += val;
}
var counter = {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return publicCounter;
}
}
Upvotes: 2