最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - What's the difference between "LexicalEnvironment" and "VariableEnvironment&

programmeradmin3浏览0评论

I'm reading the ECMAScript 2015 specification, and the terms "LexicalEnvironment" and "VariableEnvironment" are used many times. They are defined in table 23:

LexicalEnvironment: Identifies the Lexical Environment used to resolve identifier references made by code within this execution context.

VariableEnvironment: Identifies the Lexical Environment whose EnvironmentRecord holds bindings created by VariableStatements within this execution context.

The LexicalEnvironment and VariableEnvironment ponents of an execution context are always Lexical Environments. When an execution context is created its LexicalEnvironment and VariableEnvironment ponents initially have the same value.

So, I want to know how they will be different, and which situations each are used in. Could anyone explain?

I'm reading the ECMAScript 2015 specification, and the terms "LexicalEnvironment" and "VariableEnvironment" are used many times. They are defined in table 23:

LexicalEnvironment: Identifies the Lexical Environment used to resolve identifier references made by code within this execution context.

VariableEnvironment: Identifies the Lexical Environment whose EnvironmentRecord holds bindings created by VariableStatements within this execution context.

The LexicalEnvironment and VariableEnvironment ponents of an execution context are always Lexical Environments. When an execution context is created its LexicalEnvironment and VariableEnvironment ponents initially have the same value.

So, I want to know how they will be different, and which situations each are used in. Could anyone explain?

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Nov 19, 2016 at 9:24 SmallTown NESmallTown NE 6131 gold badge9 silver badges26 bronze badges 9
  • possible duplicate of Clarity on the difference between “LexicalEnvironment” and “VariableEnvironment” in ECMAScript 5? Their purpose didn't really change, only the current lexical environment is swapped more often (e.g. with every block-scope). – Bergi Commented Nov 19, 2016 at 13:29
  • Yeah,I read it before, but I still have some trouble in it. You said try {throw "some"} catch(x) { function y(){console.log(x, typeof x);} y(); }, I run it in the chrome, but no throws a ReferenceError for x @ Bergi – SmallTown NE Commented Nov 19, 2016 at 14:28
  • @SmallTownNE Thanks, I updated that answer. But the "fun fact" wasn't the gist of the post anyway - the main point is that the LexicalEnvironment changes when you enter a block scope (e.g. catch, since ES6 also normal blocks - for let and const etc) – Bergi Commented Nov 19, 2016 at 14:43
  • Thanks. I still have some questions.Can I sum up that LexicalEnvironment is static, VariableEnvironment is dynamic?(Because I read the kangax's answer) @ Bergi – SmallTown NE Commented Nov 19, 2016 at 14:53
  • you think VariableEnvironment never changes within the same execution context.But kangax's answer express that LexicalEnvironment never changes within the same execution context.It makes me confused.Could you explain it? @ Bergi – SmallTown NE Commented Nov 19, 2016 at 15:25
 |  Show 4 more ments

2 Answers 2

Reset to default 9

I post the question to offical ECMA262 organization on github, this is the answer of littledan:

A LexicalEnvironment is a local lexical scope, e.g., for let-defined variables. If you define a variable with let in a catch block, it is only visible within the catch block, and to implement that in the spec, we use a LexicalEnvironment. VariableEnvironment is the scope for things like var-defined variables. vars can be thought of as "hoisting" to the top of the function. To implement this in the spec, we give functions a new VariableEnvironment, but say that blocks inherit the enclosing VariableEnvironment.

This is a hard one. I will try to explain with some simple examples. So one important thing, in this question is also to understand the execution context.

Lexical Environment

Means where you write something in the code is important. Not all programming languages are like that, but javascript is.

So if you have a function like

function hello() {
    var myVar = 'hello';
}

Now the variable myVar sits lexically inside the function. That's physically the code that you're writing. In short, if talking about lexical environment means where it is written and what surrounds it.

Variable Environment Every time you call a function a new execution context will be created. So even myVar is declared 3 times (see next example) they do not touch each other. That's when you talk about Variable Environment

function b() {
    var myVar;
    console.log('three', myVar) // three undefined 
                                // cause myVar is newly declared in b()
                                // but has no value
}

function a() {
    var myVar = 2;
    console.log('two', myVar) // two 2
    b();
}

var myVar = 1;
console.log('one', myVar) // one 1
a();
console.log('four', myVar) // one 1

Now you where asking for the difference which I guess it is just the theoretical talk about two things. But also the lexical environment kinda knows where the variables are sitting in memory.

So that is actually the answer to your question. But I will show some more examples just to make sure where things can go wrong with misunderstanding.

Because there is also this thing called hoisting in javascript which can give you errors if you write code at the wrong place. And it can have strange behaviour. The next examples are actually very simple but all depend on Lexical Environemnt, Variable Environment, Execution Context and hoisting

console.log(myVar); // undefined
var myVar = 'hello';
console.log(myVar); // hello

but

function a() {
    console.log(myVar) // gives Error myVar is not defined
}
a();

but again:

function a() {
    console.log(myVar); // undefined no Error
                        // cause it would take myVar from global
                        // execution context 
                        // but also no error cause we define it again
                        // in this function (hoisting)
    var myVar = 0;      // define myVar newly in this lexical environment
    console.log(myVar); // 0
}

var myVar = 'hello';
a();
console.log(myVar);     // hello

But again if we do like so

function a() {
    myVar = 0;           // overwrite global myVar
    console.log(myVar); // 0
}

var myVar = 'hello';
a();
console.log(myVar);     // 0 did you expect myVar to be 0 ?

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论