-1

I have been trying to understand when a lexical environment is created in js. As far as i read the lexical environment is created in two stages, the creation phase and the execution phase, but take a look a the next simple closure.

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);

so , when makeAdder returns the function it returns a function with a parent lexical environment pointing to x, but the thing that I do not understand is why add5 has already a parent lexical environment and the inner function that is returned has not even been executed yet , so what I can infer is that the parent lexical environment is attached as soon as it encounters a function definition (the return function), is this correct ? the parent lexical environment is created when a function is declared and reached in the code and not when it is executed? and what about the lexical environment of the function that was returned, its lexical environment is created when the function add5 is executed. Please forgive me for the long text I just want to clarify when is the parent and local lexical environments are created.

Thanks in advance guys.

Oscar
  • 77
  • 8
  • I think you are asking about something that is in the implementation details of the interpreter here. – Alex Wayne Oct 23 '18 at 23:21
  • 2
    Possible duplicate of [Lexical environment example explanation](https://stackoverflow.com/questions/47352674/lexical-environment-example-explanation) – Heretic Monkey Oct 23 '18 at 23:22

1 Answers1

1

so what I can infer is that the parent lexical environment is attached as soon as it encounters a function definition (the return function), is this correct ?

Attached to the newly created function object, yes.

the parent lexical environment is created when a function is declared and reached in the code and not when it is executed?

No. The parent environment already exists when function definition is evaluated. The parent environment is the environment that contains the function declaration.

In your example:

  • Calling makeAdder creates environment A with x set to 5.
  • The inner function (function (y) {...}) is created and gets a "reference" to A.
  • The return value of makeAdder (the inner function) is assigned to add5.
  • Calling add5 creates environment B with its parent is set to A. This is possible because the function got the reference to A when it was created.
  • x is looked up in B. It's not found, so it's looked up in B's parent, A, where it is defined.
  • ...

Please forgive me for the long text I just want to clarify when is the parent and local lexical environments are created.

There are different types of environments in ECMAScript, all created at different times:

  • Declarative environment: Base of all other environments and created when evaluating a block.
  • Function environment: created when a function call is evaluated.
  • Global environment: created when a script is evaluated / when the runtime is initialized.

There are more, but these should be the most relevant ones for this question. For more info see https://www.ecma-international.org/ecma-262/8.0/index.html#sec-lexical-environments

However, at each given time, only one environment is "active" (top of the stack). Whenever a new environment is created, the currently active environment becomes its parent.

The spec defines and uses the following operations for creating new environments:

  • NewDeclarativeEnvironment ( E )
  • NewObjectEnvironment ( O, E )
  • NewFunctionEnvironment ( F, newTarget )
  • NewGlobalEnvironment ( G, thisValue )
  • NewModuleEnvironment ( E )

where E is another environment (becoming the new environment's parent) and F is a function object. NewFunctionEnvironment gets the parent environment from the function object. NewGlobalEnvironment doesn't accept a parent environment because a global environment cannot have any.


Note: Environment A also has a parent, the global environment (assuming the code is evaluated in global scope). The global environment doesn't have a parent.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143