2012-07-17 39 views
3

我有一個.js文件,我正在使用NodeJS執行。這裏是我的文件的內容:在Javascript中需要幫助理解(詞法)變量作用域

var ctry = "America"; 

function outer(msg) { 
    console.log(msg + " " + ctry) ; 
    var ctry = "Canada" ; 
} 
outer("God Bless"); 

當我運行這個文件,我希望看到「上帝保佑美國」,而是,我看到了「上帝保佑未定義」。

如果我註釋掉內部var ctry =行,我會得到「上帝保佑美國」,如果我將內部var ctry =行移到console.log上面,我會得到「God Bless Canada」。最後兩種情況似乎是合乎邏輯的,但爲什麼在console.log之後var ctry的定義會導致ctry在上面的代碼中被設置爲underfined?

回答

5

的局部變量(ctry你的情況)的範圍是在聲明它的功能整個(也就是說,彷彿變量均在函數的頂部聲明)。上面的代碼是語義上是一樣的:

function outer(msg) { 
    var ctry ; 
    console.log(msg + " " + ctry) ; 
    ctry = "Canada" ; 
} 

現在爲什麼你在輸出中獲得undefined它應該是清楚的。

+0

爲了澄清,任何var聲明都被提升到函數的頂部。實際分配發生在其寫入的行上。你重新聲明變量是一個局部變量,而不是使用全局變量,因爲你使用了關鍵字var。如果你沒有用關鍵字var重新聲明ctry,它會像你期望的那樣使用全局變量來工作。 – dqhendricks 2012-07-17 22:20:16

+0

是的。我認爲函數定義會被提升,但不知道var聲明(局部變量)也會被提升。謝謝 – bachposer 2012-07-17 23:25:10

2

當你說var ctry裏面的一個函數(只要它在函數內部並不重要),那麼會發生什麼是在函數內部調用ctry(再次,無所謂)將引用內部變量,而不是全局變量。問題是,JS解釋器只能看到一個變量的定義,但不會用值(加拿大)初始化它,直到它執行該行,因此在console.log中它尚未定義。