→ jsFiddle
function f1(){ var n=999; nAdd=function(){n+=1;}; function f2(){ alert(n); } return f2; } var result = f1(); var result2 = f1(); result(); // 999 nAdd(); result2(); // 1000 result2(); // 1000 result(); // 999
I am trying to learn JavaScript closures, but the code above just got me confused. When the first time result()
is called , it's 999. That's ok for me.
After nAdd()
is called, result2()
shows 1000. And I think this is due to function result2()
and function result()
are equals to function f1()
.
But why does the last result()
show 999 instead of 1000?
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function.
There are two main disadvantages of overusing closures: The variables declared inside a closure are not garbage collected. Too many closures can slow down your application. This is actually caused by duplication of code in the memory.
The lexical scope allows a function scope to access statically the variables from the outer scopes. Finally, a closure is a function that captures variables from its lexical scope. In simple words, the closure remembers the variables from the place where it is defined, no matter where it is executed.
This is called a JavaScript closure. It makes it possible for a function to have "private" variables. The counter is protected by the scope of the anonymous function, and can only be changed using the add function. A closure is a function having access to the parent scope, even after the parent function has closed.
Each time f1()
is called that creates a new closure with its own local n
variable.
However, the nAdd
variable is global, and so gets overwritten every time f1()
is called - which means calling nAdd()
will only ever add to the n
variable in the last closure.
UPDATE: If you want to be able to increment the values of n
in each closure independently you could do something like this:
function f1(){ var n=999; return { incrementN : function(){n+=1;}, getN : function f2(){console.log(n);} } } var result = f1(); var result2 = f1(); result.getN(); // 999 result.incrementN(); result2.getN();//999 result2.incrementN(); result2.getN();//1000 result.getN();//1000
That is, have f1()
return an object containing two methods that are not declared as globals, and that both operate on the local n
variable from the closure they belong to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With