7

In this example

var a = 1;
( function(x) {   
   function inner() {
      alert(a);
      alert(x);
      alert(y); 
   }
   var y = 3;
   inner();
})(2);

When does function inner get created? during execution time or parsing time of outer anonymous function?

What is in the scope chain of function inner?

What is the difference between the execution context and scope chain of function inner?

Thanks for enlighting me in advance!

nandin
  • 2,549
  • 5
  • 23
  • 27

2 Answers2

10

The inner function gets created just before the anonymous function is executed, by the Variable Instantiation process.

The [[Scope]] of inner when it's executed contains:

  1. The empty Variable Object of inner (it's empty because there are no variable/function declarations inside it)
  2. The Variable Object of the anonymous function, which contains x, y and inner.
  3. The Global Object, that will contain a and other properties...
    Global (3)          Anonymous VO (2)       inner VO (1)
   ________              ________              ________
  | a = 1  | <--------- | x = 2  | < -------- |        |
  | ...    |            | y = 3  |             ¯¯¯¯¯¯¯¯ 
   ¯¯¯¯¯¯¯¯             | inner  |
                         ¯¯¯¯¯¯¯¯ 

Edit: To clarify your second question:

What is the difference between the execution context and scope chain of function inner?

Are two different concepts, an execution context is created just before a piece of code (which can be either global code, function code or eval code) is executed.

I think this might be easier to explain with your code:

var a = 1;
(function(x) {        // Step 1
   function inner() {
      alert(a);
      alert(x);
      alert(y); 
   }
   var y = 3;
   inner();           // Step 3
})(2);                // Step 2

In the Step 1, the anonymous function is created, the current scope (only containing the global object) is stored in this moment on the function [[Scope]] property.

In the Step 2, this anonymous function is executed, a new execution context is created (a function code execution context), at this moment a new lexical environment is created (the Variable Object of this function is created), all function argument identifiers (in this case only x), identifiers of function declarations (inner) and identifiers of variable declarations (y) are bound as non-deletable properties of this new variable object (which is the new lexical scope).

In the Step 3 the inner function is executed, this creates a new execution context, another Variable Object is injected into the scope chain, but in this case since nothing is declared inside inner and it doesn't have any formal parameters, it will be just an empty object.

See also this answer, the first part I talk about the with statement but in the second part it's about functions.

Community
  • 1
  • 1
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • this thing is really hard to read (http://www.ecma-international.org/publications/standards/Ecma-262.htm), can you recommend a open source JS engine code? how about V8? thx! – nandin May 18 '10 at 18:40
  • 1
    @Ding, well, IMO reading code would be much more difficult, however I can recommend you the Dmitry Soshnikov [ECMA-262 In Detail Series](http://dmitrysoshnikov.com/)... – Christian C. Salvadó May 18 '10 at 18:49
7

When does function inner get created? during execution time or parsing time of outer anonymous function?

One is created each time the outer function is executed.

What is in the scope chain of function inner?

When you execute it, that execution gets a variable object (technically the spec calls this the "binding object of the variable environment"); that's backed by the variable object created for the outer function call that created inner; that's backed by the global variable object. So:

+------------------------------+
| global variable obj          |
+------------------------------+
    ^
    |
   +-----------------------------+
   | variable obj for outer call |
   +-----------------------------+
       ^
       |
      +-----------------------------+
      | variable obj for inner call |
      +-----------------------------+

What is in the execution context of function inner?

Every function call gets its own execution context. I'm not quite sure I understand what's being asked here.

You can read up on all of this stuff (if you're willing to wade through the treacle of turgid prose) in Section 10 of the spec, and in particular section 10.4.3: "Entering Function Code".

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • execution context gets created at run time, scope chain gets created at definition time (not sure it is the right term), my question is: what is the difference between the execution context and scope chain of function inner? What is the process of execution context creation? thx! – nandin May 18 '10 at 15:22
  • 1
    @Ding: Yes, the scope chain is dictated by where the function is defined. You can tell by looking at a function in the source what identifiers are in-scope for it, and where they come from. But functions don't have execution contexts, only *calls* to functions do. The execution context includes the variable object that forms the runtime mechanism of the scope chain, as well as other things, like what the `this` value should be. You clearly have an interest in actually knowing how this stuff works (which is great!) and so I can only say: Read Sect 10 (esp 10.3 & 4) of the spec for details. :-) – T.J. Crowder May 18 '10 at 15:39