EDIT: thanks for the answers, I think I get it now. It requires an understanding of scope and hoisting. Below is a new example that I think illustrates both well:
var a = function (){
alert(x);
}
var x = 1;
(function(){
var x = 2;
a();
})();
The above alerts 1. Lexical scope is illustrated by the fact that this alerts 1 and not 2, and hoisting is illustrated by the fact that the "var x = 1" line comes after the declaration of a and definition of the anonymous function with the "alert(x)". Allegedly, hoisting means that the above is equivalent to the below (source: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html):
var x;
var a = function (){
alert(x);
}
x = 1;
(function(){
var x = 2;
a();
})();
So since x is effectively initialized before the function definition, the x in "alert(x)" is the same x that subsequently gets set to 1.
Since JS uses lexical scope, the line "var x = 2" does not override the x associated with a.
Is that about right?
---original question---
I've spent pretty much all day trying to figure this out. I've read a few articles on scope and closures in Javascript, but this still eludes me.
I'm told that a function's lexical environment is created when the function is defined, not when it is executed.
So if there is no variable called x declared anywhere in my program, then what is the closure environment for the anonymous function that a points to when I do this?:
var a = func(){
var y = 7; //just for illustrative purposes
alert(x);
});
My understanding is that an environment is a mapping of variable names to values...so it would be
y: 7
x: ?
Is that correct? The following code alerts "10":
(function (){
var a = function(){
alert(x);
};
var x = 10;
a();
})();
My guess would be that when a is called, the JS checks the closure environment for a mapping for x and finds none, and subsequently checks the local environment and finds the x set to 10 by "var x = 10". Is that right?
If that were the case, then I would expect the following would also work, and yet it does not:
var a = function(){
alert(x);
};
(function (){
var x = 10;
a();
})();
What I would expect to happen is that, when a is executed, and "alert(x);" is run, it checks the closure environment for x, finds none, then checks the outer environment where "var x = 10" is and finds that x. But instead I get an error that x isn't defined.
Maybe it would help if I could know what 'preparatory' work is done by the interpreter when the anonymous function that a is set to is initially defined--i.e. when the interpreter encounters the x in "alert(x)".
Thanks