2012-12-04 43 views
1

可能重複:
Redeclare JavaScript Variable新來JS,試圖瞭解吊裝

我的下一段代碼:

var i = 11; 
alert(i); 
function a(){ 
    alert(i); 
    var i = 2; 
    alert(i); 
} 
a() 

第二alert(i)(內功能)產生undefined。我猜它與JS引擎通過代碼運行的方式有關 - 也許它不會首先存儲變量,然後再通過代碼行?

無論如何,我認爲這不是一個問題是JS,因爲它支持吊裝。我可能弄錯了 - 有沒有人關心解釋?

謝謝!

+0

有幾個關於這個問題重複的問題:這個問題(http://stackoverflow.com/questions/13630373/will-i-have-any-problems-if- i-declare-the-same-variable-multiple-times/13630592#13630592)和[this one](http:// stackoverflow。com/questions/13626094/redeclare-javascript-variable/13626288#13626288)處理此事 –

回答

4

JavaScript確實將聲明提升到它們出現的範圍的頂部,但分配發生在您期望它們的位置。您的代碼有效地解析如下:

/* Function declarations are hoisted first, which is why you can invoke a 
    function before it appears to be defined in the source */ 
function a() { 
    var i; // Declaration is hoisted (this i shadows the outer i) 
    alert(i); 
    i = 2; // Assignment to local i happens in place 
    alert(i); 
} 
var i; // Declaration is hoisted (at this point, i === undefined) 
i = 11; // Assignment happens in place 
alert(i); 
a(); 

這是詳細的in the spec。當進入一個新的執行上下文中,發生以下情況:

對於每個VariableDeclarationVariableDeclarationNoIn d代碼,在源文本順序做

  • DN標識符 in d
  • varAlreadyDeclared是調用env的傳球DN作爲參數 HasBinding具體方法的結果。
  • 如果varAlreadyDeclaredfalse,然後
    • 呼叫env的 CreateMutableBinding傳遞DNconfigurableBindings作爲參數具體方法。
    • 呼叫env的 SetMutableBinding傳遞DNundefined,並嚴格作爲參數具體方法。
+0

當解釋器遇到一個沒有關鍵字'var'的函數變量之前不會出現懸掛? OP正在創建一個新的變量'i',它是函數範圍的,對嗎? –

+0

@limelights - 在進入任何執行上下文時發生吊裝。當控制進入'a'函數時,解釋器會在開始執行代碼之前查找任何聲明並在新執行上下文的環境記錄中爲其標識符創建綁定。 –

+1

事實上,函數a()的第一行'var i;'對函數有一個局部範圍,所以直到'i = 2;' – ncremins