2014-10-10 153 views
2

JavaScript指南中有一個關於變量範圍的語句:「JavaScript中的變量在某種意義上被」懸掛「或被提升到函數或語句的頂部,但變量不是初始化還會返回一個未定義的值。「JavaScript變量範圍返回「未定義」

/** 
    * Example 2 
    */ 
    // will return a value of undefined 
    var myvar = "my value"; 

(function() { 
    console.log(myvar); // undefined 
    var myvar = "local value"; 
})(); 

我的問題是:爲什麼「console.log(myvar);」會返回undefined?我認爲第一行已經初始化了myvar這個值是「我的價值」。

+1

你的代碼示例具有相同名稱的兩個變量,一個本地的函數初始化MYVAR之前,那是被記錄的一個。 – nnnnnn 2014-10-10 02:52:45

+0

忘記術語「提升」,這是一個分心。在執行任何代碼之前處理變量和函數聲明。 **然而**,初始化在執行過程中發生。因此,儘管變量從一開始就存在,但在賦值執行之前它不會被賦值。 – RobG 2014-10-10 03:05:47

回答

4

因爲所有變量聲明將自動提升至其定義功能塊的頂部,這樣的代碼:

(function() { 
    console.log(myvar); // undefined 
    var myvar = "local value"; 
})(); 

其實這是JS的解釋:

(function() { 
    var myvar; // declares a new local variable that covers up the global name 
    console.log(myvar); // undefined 
    myvar = "local value"; 
})(); 

這應該告訴你爲什麼本地定義的myvarconsole.log()輸出的內容,它已被定義,但尚未初始化,因此它顯示爲undefined

的本地定義myvar重寫/覆蓋了全局定義的一個,所以當你在你的函數訪問myvar,你只能獲得局部定義變量(不管是尚未還是未初始化)。

查看同一主題的其他一些參考:

How do JavaScript variables work?

JavaScript variable undefined vs not defined

One var per function in JavaScript?

JavaScript 'hoisting'


如果喲你刪除你的函數中的var(所以你只是引用一個變量,而不是聲明一個新變量),那麼你將只有一個全局變量名爲myvar,你會得到它看起來像你可能會期待的行爲:

var myvar = "my value"; 

(function() { 
    console.log(myvar); // outputs "my value" 
    myvar = "local value"; 
})(); 
+0

請注意,OP令人困惑,因爲她的示例具有兩個相同名稱的變量:該問題明確提到將值分配給全局變量。 – nnnnnn 2014-10-10 02:57:28

+0

@nnnnnn - 是的,我已經解決了一些編輯。 – jfriend00 2014-10-10 02:57:50

+0

在ES5中,[*變量在創建時被初始化爲'undefined'](http://ecma-international.org/ecma-262/5.1/#sec-12.2),所以它們的值總是被定義的,它們本質上是「初始化」兩次。 ;-) – RobG 2014-10-10 03:09:01

2

這裏你的功能是一個自我調用功能。自調用表達式會自動調用(啓動),而不會被調用。提升適用於變量聲明和函數聲明。

var myvar = "my value"; 

(function() { 
    console.log(myvar); // undefined 
    var myvar = "local value"; 
})(); 

所以這裏的功能調用它自身甚至與指定的值

+0

全局變量在函數被調用之前被初始化。但是,未定義的值被記錄屬於同名的局部變量,局部變量的初始化不受函數調用方式的影響。涉及立即調用的函數表達式的事實是不相關的。 – nnnnnn 2016-03-27 10:32:18