You have two questions here. In the future you might consider posting two separate questions when you have two questions.
When creating a closure in Javascript, are all variables in the scope at the time of the closure's creation "enclosed" in it?
You do not state which of many versions of "JavaScript" you are talking about. I'm going to assume you are talking about a correct implementation of the ECMAScript 3 language. If you are talking about some other version of "JavaScript", say which one you're talking about.
ECMAScript 5 has updated rules on how lexical environments and "eval" work. I have not been a member of Technical Committee 39 since 2001, and I have not been keeping up-to-date with recent changes to the ECMAScript 5 spec; if you want an answer in the context of recent ECMAScript 5 rules, find an expert on that specification; I'm not it.
The answer to your question in the context of ECMAScript 3 is yes. The ECMAScript 3 specification is very clear on this point, but you don't need to look at the spec to know that this must be the case:
function f()
{
var referenced = 1;
var notReferenced = 2;
var func = function ()
{
alert(referenced);
alert(eval("notReferenced"));
}
return func;
}
f()();
How can "eval" work correctly if "notReferenced" is not captured?
This is all explained in the ECMAScript specification, but I can briefly sum it up here.
Every variable is associated with a "variable object", which is the object that has properties whose names are the names of the variables. The variable object for the function f is identical to the activation object of f -- that is, the object that is magically created every time f is invoked. The variable object has three properties: "referenced", "notReferenced" and "func".
There is a variable object called the "global object" which represents the code outside of any function. It has a property "f".
Every execution context has a scope chain, which is the list of objects whose properties are searched when trying to evaluate an identifier.
Every function object has a scope chain associated with it, which is a copy of the scope chain that was in effect when the function was created.
The scope chain associated with "f" is the global object.
When execution enters "f", the current scope chain of the execution context has the activation object of "f" pushed onto it.
When "f" creates the function object assigned to "func", its associated scope chain is a copy of the current scope chain of the execution context -- that is, the scope chain that contains the activation of "f", and the global object.
OK, so now all the objects are set up correctly. f returns func, which is then invoked. That creates an activation object for that function. The scope chain of the execution context is fetched from the function object -- remember, it is the activation object of "f" plus the global object -- and onto that copy of the scope chain we push the current activation object. Since the anonymous function we are now executing has neither arguments nor locals, this is essentially a no-op.
We then attempt to evaluate "alert"; we look up the scope chain. The current activation and the "f" activation do not have anything called "alert", so we ask the global object, and it says yes, alert is a function. We then evaluate "referenced". It's not on the current activation object, but it is on f's activation object, so we fetch its value and pass it to alert.
Same thing on the next line. The global object tells us that there are methods "alert" and "eval". But of course "eval" is special. Eval gets a copy of the current scope chain as well as the string argument. Eval parses the string as a program and then executes the program using the current scope chain. That program looks up "notReferenced" and finds it because it is on the current scope chain.
If you have more questions about this area then I encourage you to read chapters 10 and 13 of the ECMAScript 3 specification until you thoroughly understand them.
Let's take a deeper look at your question:
When creating a closure in Javascript, are all variables in the scope at the time of the closure's creation "enclosed" in it?
To definitively answer that question you need to tell us precisely what you mean by "the closure" -- the ECMAScript 3 specification nowhere defines that term. By "the closure" do you mean the function object or the scope chain captured by the function object?
Remember, all these objects are mutable -- the scope chain itself is not mutable, but every object in the chain is mutable! Whether or not there was a variable "at the time" of the creation of either the scope chain or the function object is actually a bit irrelevant; variables come, variables go.
For example, variables that have not yet been created at the time of the function object's creation can be captured!
function f()
{
var func = function ()
{
alert(newlyCreated);
}
eval("var newlyCreated = 123;");
return func;
}
f()();
Clearly "newlyCreated" is not a variable at the time the function object is created because it is created after the function object. But when the function object is invoked, there it is, on f's activation/variable object.
Similarly, a variable that exists at the time a nested function object is created can be deleted by the time the function object is executed.