问题
I do not yet have a basic understanding of JavaScript closures;
I have a question regarding a specific situation that perhaps is also basic and common example:
Count from 1 to 3 in 3 seconds
See JSFiddle here: http://jsfiddle.net/nAh8x/
The code:
var i,
t;
t = 0;
// Case A
for( i=1; i<=3; i++ ) {
setTimeout( function() { log(i); }, t );
t += 1000;
}
// Case B
for( i=1; i<=3; i++ ) {
setTimeout( wrapper(i), t );
t += 1000;
}
function wrapper(i) {
return function() { log(i); };
}
// Log utility function
function log(msg) {
$('#log').append( msg + '<br />' );
}
Case A doesn't work.
It's clear to me why: every time the function inside setTimeout is called and accesses the i variable, its value has already reached 4.
Case B works.
When wrapper(i) is called it returns
function() { log(i); };
and the above return value (a function) is what goes inside setTimeout. What goes inside setTimeout is exactly the same as Case A
But this time, the i variable have been "frozen" with the value at the time of the call.
Why using the wrapper function let the passed value to be frozen?
That's not completely clear to me.
回答1:
The wrapper function has it's own i
that is locally scoped to it.
This receives the value of the other i
at the time wrapper
is called.
It might be clearer if you rewrote it as:
function wrapper(notI) {
return function() { log(notI); };
}
回答2:
Closure is an environment which is created with variables scope and nested function by calling of outer function,
Every time the wrapper()
is called there would created each different environment for below's function
function wrapper(i) {
return function() { log(i); };
}
Here is the i
's value would be same as when wrapper()
is invoked. Each time the i
's value would be private for that particular environment which made by invoking wrapper()
outer function.
回答3:
The variable i
used inside wrapper
is the one the has been passed (as a copy) as the formal parameter to wrapper
. It's not the same i
as the one inside your for
loop - you could rename that variable to anything you like and the code would still work.
It's frozen because it has the value it had each time wrapper
was originally called.
来源:https://stackoverflow.com/questions/21363295/understanding-javascript-closures-freeze-variable-passed-to-callback