JavaScript Closure question: why is the second call to outerFn creating a new instance of outerVar?
I have a JavaScript question. Let me quote from the book 'Learning jQuery', page 389-390. The question concerns Closures.
I don't understand why "the second call to outerFn() is not resetting the value of outerVar, but [is], rather, creating a new instance of outerVar, bound to the scope of the second function call.
What is it about JavaScript that would make this so? What do I need to know about JavaScript so that I could infer this for myself?
The rest of the email is the quotation from the book.
function outerFn() {
var outerVar = 0;
function innerFn() {
outerVar++;
$('#example-7').print('outerVar = ' + outerVar);
}
return innerFn;
}
var fnRef = outerFn();
fnRef();
fnRef();
var fnRef2 = outerFn();开发者_开发百科
fnRef2();
fnRef2();
Now our function calls have more interesting behavior: outerVar = 1 outerVar = 2 outerVar = 1 outerVar = 2 We get a mix of the two earlier effects. The calls to innerFn() through each reference increment outerVar independently. Note that the second call to outerFn() is not resetting the value of outerVar, but rather creating a new instance of outerVar, bound to the scope of the second function call. The upshot of this is that after the above calls, another call to fnRef() will print the value 3, and a subsequent call to fnRef2() will also print 3. The two counters are completely separate.
Well, this is the whole idea of closures. As the firs paragraph of the above wiki link states:
In computer science, a closure (also lexical closure, function closure or function value) is a function together with a referencing environment for the nonlocal names (free variables) of that function. Such a function is said to be "closed over" its free variables. The referencing environment binds the nonlocal names to the corresponding variables in scope at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure itself.
This behavior is not a particularity of javascript - it happens this way in every language that offer support for closures
You might be over thinking it.
As always, every time a call to outerFn
is made, it will create a new outerVar
variable for that particular invocation of the function -- it's part of it's local scope. Thus, any functions that are within the scope of the particular call to outerFn
that are returned (or passed along somehow) will have continue to have access to that scope -- a closure.
Without closure functions would be limited to using variables that are passed in as arguments.
To be able to make use of variables declared outside of the function those variables must be captured when the function is created. Each time the function is created it captures the complete set of variables that are currently in scope.
outerVar is simply a local variable in the function outerFn. Every invocation of outerFn creates a new set of local variables specific to that particular function call.
If you want outerVar to retain it's value from one invocation to another, then you need to define it in a scope outside of outerFn that survives between your function calls (it can be global or some other scope above the function level that survives).
精彩评论