Why a nested IIFE is not creating closure?
I'm reading this resource trying to understand how closure works in Javascript.
I understood that every time a function is called outside its normal lexical scope, it creates closure, being able to access the enclosing function variables and using them to store state.
This works in my_module.incrCounter();
below (which keeps increasing the counter), but why it doesn't work in my_module.incrLocalCounter();
, which keeps returning 1 every time?
Shouldn't the IIFE inside incrLocalCounter
create closure over local_counter
?
var my_module = (function tlModule(){
var counter = 0;
function incrCounter(){
counter++
console.log(counter);
};
function incrLocalCounter(){
var local_counter = 0;
(function () {
local_counter++
console.log(local_counter)
})();
};
return {
incrCounter: incrCounter,
incrLocalCounter: incrLocalCounter
}
})();
Your "nested" IIFE logs 1 every time because the variable that is incremented is always initialized to 0 before the IIFE runs. That is, inside that nested function, local_counter
always starts off at 0.
If you move the var
declaration for local_counter
to outside incrLocalCounter()
, then you'll see it increment. Alternatively, you could have incrLocalCounter()
return a function and have that be the property value you return:
function incrLocalCounter(){
var local_counter = 0;
return function () {
local_counter++
console.log(local_counter)
};
};
return {
incrCounter: incrCounter,
incrLocalCounter: incrLocalCounter() // <-- call the function
}
Shouldn't the IIFE inside incrLocalCounter
create closure over local_counter
?
It does. local_counter
is at 0
at that time. Then it increments it from 0
to 1
by executing the IIFE. Then it returns 1
. And it does this same sequence (including setting local_counter
to 0
) each time you call incrLocalCounter
. The difference is not that incrLocalCounter
has an IIFE; the difference is whether the variable being incremented is being reset within the function or not.
下一篇: 为什么嵌套的IIFE不创建闭包?