2017-03-04 67 views
-1

所以,我想在javascript中掌握範圍鏈的概念,因此我創建了下面的示例來檢查我是否正確。
注:我熟悉以下概念(執行上下文和詞法環境)。範圍鏈示例

例子:

function test(){ 
    function test2(){ 
     //This prints 2 as expected 
     console.log(a); 
    } 
    //This should print 1 but instead it prints undefined 
    console.log(a); 
    var a = 2; 
    test2(); 
} 

var a = 1; 
test(); 

舉例來說,如果我的評論如下:

//var a = 2; 

然後在這兩種情況下的輸出爲1

+0

因爲JavaScript變量懸掛進行治療。即使在執行之前,函數中的var a也是引用。函數內的'console.log(a)'和'test2'內的'a'指的是本地的'a'(*仍然是'undefined' *),而不是全局的'a'。 –

+0

我知道他們被吊起來了。但是我從外部環境獲得的參考資料有哪些? – sterg

回答

1

你應該看看到起重概念在JavaScript中。 在進入執行步驟之前,JS引擎將移動塊頂部的所有聲明。

關於您的爲例:

function test(){ 
    function test2(){ 
     //This prints 2 as expected 
     console.log(a); 
    } 
    //This should print 1 but instead it prints undefined 
    console.log(a); 
    var a = 2; 
    test2(); 
} 

var a = 1; 
test(); 

會這樣

var a; // initialized to undefined 
function test(){ 
    var a; // initialized to undefined [which is printed] 
    function test2(){ 
     //This prints 2 as expected 
     console.log(a); 
    } 
    //This will print undefined which is the actual value of a 
    console.log(a); 
    a = 2; 
    test2(); 
} 

a = 1; 
test(); 

這就是爲什麼它打印未定義

+0

雖然我從外部環境獲得的參考資料呢? – sterg

+0

我不喜歡「提升」這個詞,因爲它引入了混亂,就像OP已經證明的那樣。我更願意將其解釋爲EMCA-262所做的,即所有聲明都在進入執行環境時執行,並且在執行開始之前進行處理,並且在執行期間在代碼中出現分配時進行分配。也許更長,但我認爲更容易理解。 ;-) – RobG

+0

當在JS中使用變量時,引擎將在進入外部環境之前在本地塊或當前閉包中進行搜索,正如您在代碼第二版本中看到的那樣'var a;'在本地被懸掛並聲明初始值爲'undefined' –