2013-02-22 20 views

回答

7

兩者都是組分( (from the spec):

LexicalEnvironment

標識用於解決此執行上下文中通過代碼所做標識符引用Lexical Environment

VariableEnvironment

標識,其環境記錄Lexical Environment保持該執行上下文內VariableStatements和FunctionDeclarations創建綁定。

下段解釋了爲什麼他們需要的是不同的:

當一個執行上下文中創建了LexicalEnvironment和VariableEnvironment組件最初具有相同的值。變量環境組件的值永遠不會更改,而LexicalEnvironment組件的值在執行上下文中的代碼執行期間可能會更改

這並不經常發生,通常都是指相同的Lexical Environment。在Why do catch clauses have their own lexical environment?這個問題中給出了一個改變詞法環境的好例子 - 見§12.14。在規範中我發現的其他地方是With Statements§12.10),其中Object Environment Record動態用於標識符解析 - 但變量/函數聲明是靜態的。

4

據我瞭解,這些都是用來指同一類型的實體(詞法環境)只是叫法不同。由於目的不同,它們有不同的名稱。

LexicalEnvironment用於解析標識符,而VariableEnvironment用於聲明變量和函數。

它們都是爲每個執行上下文創建的詞法環境(=環境記錄+可選外部詞法環境;也稱爲作用域鏈)。

執行上下文的LexicalEnvironment和VariableEnvironment組件總是詞法環境。當執行 上下文創建時,其詞彙環境和變量環境 組件最初具有相同的值。所述 VariableEnvironment分量的值不會改變而 LexicalEnvironment分量的值可能的代碼 執行期間的執行上下文內以僞代碼改變

實施例:

// VariableEnvironment (global) = { __outer__: null } 
// LexicalEnvironment = VariableEnvironment (global) 

(function foo() { 

    // VariableEnvironment (A) = { x: undefined, __outer__: global } 
    // LexicalEnvironment = VariableEnvironment (A) 

    var x; 

    (function bar(){ 

    // VariableEnvironment (B) = { y: undefined, __outer__: A } 
    // LexicalEnvironment = VariableEnvironment (B) 

    var y; 

    x = 2; 

    // VariableEnvironment (A) = { x: 2, __outer__: global } 
    // LexicalEnvironment is still the same as VariableEnvironment (B) 

    })(); 

})(); 
+0

你和Bergi似乎對「LexicalEnvironment組件的價值可能會改變」有不同的解釋。如果你錯了,請糾正我的錯誤,但你似乎在談論詞彙環境組件的價值變化(例如,使用變量賦值),而Bergi的答案是關於整個LexicalEnvironment對象被替換的情況。現在我很困惑! – bfavaretto 2013-03-01 19:28:47

+0

我的意思是「如果*我錯了」! :) – bfavaretto 2013-03-01 19:40:32

+0

我不認爲我們有不同的解釋。但看看我的例子,我可以看到它可能會令人困惑。對不起:)變量賦值當然不會改變LexicalEnvironment的任何內容。我只是想表明VE從一種功能上下文變化到另一種功能上下文,而大多數情況下,LE只是當前VE的參考。 @Bergi關於'catch'和'with'的提及是正確的。當LE和VE引用不同的環境時,這兩種情況(不需要'with'和'catch'中的新VE;只有新的LE-能夠解析附加標識符) – kangax 2013-03-01 19:48:39