The inner function is created just before the anonymous function is executed using the Variable Instantiation process.
[[Scope]] inner when executed, contains:
- Empty
inner variable object (it is empty because there are no variable / function declarations inside it) - An anonymous function variable object containing
x , y and inner . - A global object that will contain
a and other properties ...
Global (3) Anonymous VO (2) inner VO (1)
________ ________ ________
| a = 1 | <--------- | x = 2 | <-------- | |
| ... | | y = 3 | ¯¯¯¯¯¯¯¯
¯¯¯¯¯¯¯¯ | inner |
¯¯¯¯¯¯¯¯
Change To clarify your second question:
What is the difference between the execution context and the visibility chain of the inner function?
There are two different concepts, the execution context is created immediately before the code fragment (which can be either global code, function code, or eval code).
I think this might be easier to explain with your code:
var a = 1; (function(x) {
In Step 1, an anonymous function is created , the current region (only containing the global object) is stored at this moment on the [[Scope]] function property.
In Step 2 , this anonymous function is executed, a new execution context is created (the context of the function code execution ), at this moment a new lexical environment is created (the Variable Object of this function is created), all identifiers of the function arguments (in this case, only x ), identifiers of function declarations ( inner ) and variable declaration identifiers ( y ) are related as non-removable properties of this new variable object (which is the new lexical scope).
In step 3 , the inner function is executed, this creates a new execution context, another variable object is introduced into the scope chain, but in this case, since it has no formal parameters inside, it will be an empty object.
See also this answer, in the first part I will talk about the with statement, but in the second part about functions.