Wanting to get something straight here…so I have 2 questions
The function below creates a closure.
function Foo(message){
var msg = message;
return function Bar(){
this.talk = function(){alert(msg); }
}
};
Q: Which function is the closure, Foo or Bar?
I always thought the closure to be Foo, because it closes-over Bar once Bar is returned.
Next…
Below is the definition of an anonymous function:
()();
Q: Is the inner-function within this anonymous function also a closure?
(function(){ /* <-- Is this function also a closure? */ })();
You need to use first principles here. Javascript uses lexical scoping. This means the scope of an execution context is determined by how the code is defined (lexical).
I would say the definition of the function
Baris what causes the closure to be created, becausemsgis “closed-in” in the function.The actual creation of the closure happens at runtime (which is somewhat of a tautological statement, since nothing in a computer program happens until it is run), because in order to determine the value of
msg, inBar, whenBaris executed, the interpreter needs to know the value of the variable whenFoois executed, and so on up the chain.I’ll give two answers to your question. The pedantic answer is: neither function by itself is the closure. It’s the definition of variables within functions, combined with the execution context of functions when they are run, that is defines the closure. The common answer is: any function which closes over a variable is a closure (Bar in your case).
Consider the problem everyone encounters when using Javascript.
Most people would say this would produce the output ‘hi 1’ followed by ‘hi 2’ followed by ‘hi 3’. However, it produces ‘hi 3’ 3 times. If just the definition of the function being added to the array, while using variables defined in the outer function, created the closure, how can this be?
It’s because you need the execution context to define the closure, which doesn’t happen until runtime. At the execution of the functions in the array,
ihas the value3. In theforEachstatement, that’s the execution context, which is why the output always uses 3.