1

I read a lot of articles, I was very confused, I also read the ES6 official documentation. When creating an execution context, LE and VE initially point to the same Lexical Environment. But then the document says let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment.

Since it's the same, Do they refer to lexical environments that have both let-defined and var-defined variables? Or do we create a new lexical environment when we encounter let/const, and then have LE point to this new lexical environment, as I have shown below? here is the code

0:  function do_something() {
1:     var a = 1;
2:     let b = 2;
3:     while (true) {
4:         var c = 3;
5:         let d = 4;
6:         console.log(b);
7:         break;
8:     }
9:  }
10:
11: do_something();

When executing a function, create the execution context as follows,with LE and VE pointing to the same lexical environment

ExecutionContext:
    LexicalEnvironment:
        a -> undefined, c -> undefined
        outer: global
    VariableEnvironment:
        a -> undefined, c -> undefined
        outer: global
    ...

But there is let/const, so a new lexical environment is created and LE points to the newly created lexical environment.

ExecutionContext:
    LexicalEnvironment:
        b -> uninitialized
        outer: VariableEnvironment //here should VariableEnvironment,也就是当前执行上下文的词法环境
    VariableEnvironment:
        a -> undefined, c -> undefined
        outer: global
    ...

When you encounter while, you need to create a new block-level scope that is, a new lexical environment

ExecutionContext:
    LexicalEnvironment:
        d -> uninitialized
        outer:
            LexicalEnvironment
                b -> 2
                outer: VariableEnvironment
    VariableEnvironment:
        a -> 1, c -> undefined
        outer: global
    ...

and When we leave the while block we restore the original lexical environment.

ExecutionContext:
    LexicalEnvironment:
        b -> nothing
        outer: VariableEnvironment //here should VariableEnvironment,也就是当前执行上下文的词法环境
    VariableEnvironment:
        a -> undefined, c -> undefined
        outer: global
    ...

Following this model, I feel that variable lookup can be done normally, but I don't know it's right or not. I read a lot of articles that separate LE and VE, but the documentation says that they start with the same value, which makes me very confused

I looked at the official ES6 documentation, as well as many other articles.

Ah, I found that this seems to be unable to explain the situation of encountering closures.

1_sy
  • 29
  • 2

1 Answers1

1

Since it's the same, do they refer to lexical environments that have both let-defined and var-defined variables?

Yes. The rules for initialising the environment guarantee that there are no naming conflicts between lexical and var-scoped variables, i.e. it does not need to distinguish between them by putting them in different environments but it just throws an exception when encountering a let (or const, class etc) and a var (or function) declaration with the same name.

Or do we create a new lexical environment when we encounter let/const?

No. The environments are created and initialised with the declared variables when the new scope is entered, typically when calling a function or entering a block.

So why is this VariableEnvironment component of the execution needed at all, you might wonder? Actually, its only use is an edge case: direct eval calls in sloppy mode. They can introduce variable and function declarations in an existing environment record, namely the VariableEnvironment of the current execution context in which the eval() call was made.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Amazing, the original lexical environment has all the let/const-defined var-defined property values? Will the Lexical Environment Components and Variable Environment Components be distinguished later?Or How to understand the sentence `let and const declarations define variables that are scoped to the running execution context's LexicalEnvironment` in the official document – 1_sy Jul 23 '23 at 09:55
  • They are distinguished insofar as that the LexicalEnvironment changes when a block scope is entered but the VariableEnvironment doesn't. The key in the note you read is "*The variables are created when their containing Environment Record is instantiated*", and are found via [static scope analysis](https://262.ecma-international.org/14.0/#sec-syntax-directed-operations-scope-analysis). – Bergi Jul 23 '23 at 11:11
  • I understand, thank you very much :) – 1_sy Jul 23 '23 at 11:52