2016-01-22 56 views
3

ES6標準提出了Temporal Dead Zones,在評估詞法綁定之前,無法以任何方式創建變量引用。那麼在詞法環境初始化時變量創建是什麼意思呢爲什麼在存在TDZ時提升變量

  1. 程序員?
  2. 編譯器?

使用var聲明可能意味着一些以前程序員變量的聲明,但現在到位並開始JavaScript的行爲,如Java爲此目的TDZ?除了JavaScript解釋器的工作方式之外,還有什麼原因可以使我們首先提升(因此TDZ)呢?

如果由於執行順序而在代碼中稍後遇到詞法綁定,即使代碼出現在詞法上時也會發生什麼?

let abc = f(); 
let b; 
f(){ return b;} 

傳統上,像java這樣的編程語言是否會創建變量?遇到變量聲明時?或者當詞法作用域被初始化時?

+1

也許是因爲很多問題的,可以generaly由谷歌在大多數 –

+0

沒有真正得到解決,我嘗試了其中的大部分,比如像Java這樣的語言創建變量並空手而來。大多數資源TBZ有很好的解釋,但他們沒有解釋爲什麼我們首先需要它,因爲現在如果變量懸掛起來就沒有關係(僅限塊範圍元素) – sasidhar

+0

@sasidhar,有多個不同的步驟來「創建「 一個變量。你在說什麼時候他們被認爲是變數?你在談論他們的內存地址空間何時填充?許多許多語言以不同的方式「創造」變量,你必須看看每種語言在語言環境中是如何處理的。 – Jay

回答

1

我有一種感覺,TDZ的創建與它是var的一個非常卑鄙的步驟有關,而如果他們要採用似乎更符合邏輯的方法,即使沒有標識符存在,引擎也會有必須經歷更加深入的改變。至於你的問題的第二部分,在提及其他語言「創建」變量的時候,還有很多其他重要因素需要考慮,你似乎忽略了這些因素,比如語言解釋與編譯,以及有多個「創建」一個變量的不同步驟。它在許多不同的情況下行爲不同,並且沒有單一的答案。事實上,這是爲什麼有很多不同的語言的一個重要原因。

至於你的編碼問題,這取決於你打電話給你的f函數,因爲函數聲明是在javascript中懸掛的。如果您在b宣佈之前調用它,那麼您在TDZ中,並且b不能被引用。它的行爲非常相似,就好像你只是簡單地把return b這個函數調用的地方。

老實說,好像有一些基本的javascript誤解,以及一般的計算機語言。 Javascript並不像Java那樣「表現得更像」,實際上新的let關鍵字具有非常細微的行爲,比如能夠被塊範圍化,與java中的類型/變量聲明相比。我建議不要試圖從其他語言的角度思考ES6的變化; javascript不像很多其他語言,如果你這樣做,將很難理解這些概念以及如何使用javascript進行編程。


編輯:

至於爲什麼會有變量和函數聲明提升,這是easily googlable.

1

那麼在初始化詞法環境時變量創建對程序員意味着什麼呢?

並不多。程序員只打算使用聲明和初始化的變量。

該變量在整個範圍內(從頭開始)僅表示錯誤會更容易被捕獲,因爲變量在初始化之前的使用失敗(有例外)而不是靜靜地被解析爲外部-scope(全局?)變量。這也意味着標識符,無論它在哪個範圍內使用,都始終指向局部變量 - 這正是我們對範圍的期望。

那麼初始化時詞彙環境時的變量創建對於編譯器意味着什麼?

詞彙環境在執行期間不會改變其結構。已知範圍內標識符的靜態解析使編譯成爲可能,並且執行速度更快。

就像一個反例,考慮這件事:

var x = "global"; 
var code = "var x = 'local';"; 
(function() { 
    "use sloppy"; 
    function test() { 
     console.log(x); // what do you think does `x` refer to? 
    }     // It's hard to understand as a developer, 
         // now imagine being a compiler that tries to optimise `test`. 
    test(); 
    eval(code); 
    test(); 
}()); 

當詞法綁定在代碼 後來遇到會發生什麼,由於執行的順序,即使代碼之前,它似乎詞彙?

b在初始化之前被調用到f()使用。訪問它會拋出一個TDZ異常。
You can try it online

相關問題