How can one understand closures in Javascript?
In general terms, a closure is a function bound to one or more external variables. When it is called, the function is able to access these variables. In JavaScript, closures are often implemented when functions are declared inside another function. The inner function accesses variables of the parent one, even after the parent function has terminated
In this statement, "a closure is a function bound to one or more external variables", does it mean we can do this : var myFun = Function(msg){...};
is it correct ?
What does it mean "even after the parent function has terminated"?
3 Answers 3
closure is a function bound to one or more external variables
An example of this concept is that the function bar is bound to the external variables x, y, and z:
function foo(x, y) {
var z = 3;
return function bar(a, b, c) {
return (a + b + c) * (x + y + z);
};
}
var closure = foo(1, 2);
closure(5, 6, 7); // (5 + 6 + 7) * (1 + 2 + 3) = 24
The variable closure
refers to the inner function bar
returned from the call to foo
. Invoking closure
is like reentering the scope within foo
, which gives visibility into all of foo
's local variables and parameters.
even after the parent function has terminated
This means that after foo
is executed, the returned function stored in the closure
variable persists the state of foo
. You can even create multiple independent closures by invoking foo
again:
var closure = foo(1, 2);
closure(5, 6, 7); // (5 + 6 + 7) * (1 + 2 + 3) = 24
var closure2 = foo(0, 0);
closure2(5, 6, 7); // (5 + 6 + 7) * (0 + 0 + 3) = 21
/* closure2 does not affect the other closure */
closure(5, 6, 7); // (5 + 6 + 7) * (1 + 2 + 3) = 24
-
It doesn't persist the state of
foo
so much as creates a special scope containing (1) the returned function and (2) all the external variables referenced at the time of the return (x
,y
, andz
). This special scope is called a closure. Case in point... if you had another var defined infoo
that was not referenced in the return function, it would not exist in the closure scope.Daedalus– Daedalus2013年03月27日 19:09:23 +00:00Commented Mar 27, 2013 at 19:09 -
I think we're saying the same thing in different ways. "persist" = create special scope, "state of
foo
" = everything in scope tofoo
at the time.Rick Viscomi– Rick Viscomi2013年03月27日 19:14:47 +00:00Commented Mar 27, 2013 at 19:14 -
1@RickViscomi! Hi! Your code example is missing a closed curly brace!
}
.Jess– Jess2013年04月04日 02:29:18 +00:00Commented Apr 4, 2013 at 2:29 -
1An interesting counter example has been brought to my attention, so it seems your answer was indeed fully correct: stackoverflow.com/questions/15801471/…Daedalus– Daedalus2013年04月04日 02:57:13 +00:00Commented Apr 4, 2013 at 2:57
-
1Thanks Jessemon for bringing it up and Ian for making the edit. Daedalus, I didn't fully understand the point you were making until I read the counter example in that question you referenced. I'm glad you stuck your neck out; we're all a little wiser for it :)Rick Viscomi– Rick Viscomi2013年04月04日 15:02:02 +00:00Commented Apr 4, 2013 at 15:02
I'm not sure where you are quoting from, but it sounds like it's referencing when the parent function has finished running.
Your interpretation of external variables is incorrect. It really means it can do this:
function make_closure() {
var x = 20;
return function() {
console.log(x);
};
}
var closure = make_closure();
closure(); // Displays 20
-
2i think the important point is why this is a closure. The closure is created around
x
, which usually would fall out of scope when you returned from themake_closure()
call, but is forced to be kept around because the function returned references it.Daedalus– Daedalus2013年03月27日 19:01:29 +00:00Commented Mar 27, 2013 at 19:01
var myFun = Function(msg){...};
, you are assigning a function to a variable, which is not a closure by itself.