It occurs to me that there may be a terminology issue at play here in conflicting answers. There is a design concept called a closure which one might say is the design of the code that allows there to be a closure. That would obviously occur in the declaration of the code. This is a design concept, but since no code has yet executed, there is no actual object that contains values of variables, references to functions, etc...
There is also the actual function object that persists beyond the time its parent function is executed which makes a closure actual work. That "closure object" is created at execution time and, in fact, a new object is created each time the function is executed.
An actual closure object in your case is created at the time foo()
is executed. And, in fact, each time you execute it (and save the return value into a variable), a new closure is created. The code declaration creates the opportunity for a closure, but an actual closure itself is not created until you execute the function foo
.
Here's what happens in this code:
function foo(i) {
function inner() {
return i;
}
return inner;
}
var f = foo(3);
var result = f();
First you declare the foo()
function. It is declared to return a reference to the inner()
function. This sets up the opportunity for a closure, but no closure is yet created.
Then, when you execute f = foo(3)
, the function foo
is executed. This creates a function scope object (in the interpreter). The argument i
in this function scope object has the value of 3
in this particular execution of foo
and thus in this scope object. As foo
executes, it returns a reference to inner
which is then assigned to the variable f
. So, the variable f
contains a reference to inner()
.
Normally, when a function finishes executing, it's function scope object is garbage collected (e.g. freed), but in this case inner
still has references to that scope object and f
contains a reference to that invocation of inner
. So, that scope object is not eligible for garbage collection and stays alive. This is called a closure. Because something that lives on has a reference to something inside the function scope, it can't be garbage collected like it would normally be.
The act of defining the functions creates the opportunity for a closure, but the actual closure is created at execution time each time foo()
is run.
In fact, if you executed f = foo(3)
, you create one closure and if you execute g = foo(4)
, you create yet another closure. Each time you execute foo
and save the return value in a variable, a closure is created. Keep in mind that this type of closure is really just a function scope object that can't be immediately garbage collected because some code has retained references to objects in that function scope beyond the lifetime of the function itself.
For me personally, closures were easier to understand when I really just thought about them from the garbage collector point of view. They are simply function scope objects (which all functions have) that can't yet be garbage collected because some code retains a reference to something inside of them. And, the most common way of creating this type of closure is when outside code is given references to local functions inside the parent function.