2011-03-31 204 views
22

對不起這個問題,但這個問題真的搞砸了我的一天。爲什麼局部變量會殺死我的全局變量?

下面的代碼提醒理所應當:

var globalId='10'; 
function check(){ 
    alert(globalId); 
} 
check(); 

但是,這下面的代碼警報未定義

var globalId='10'; 
function check(){ 
    alert(globalId); 
    var globalId; 
} 
check(); 

我知道,如果我在一個函數聲明一個變量它是一個局部變量,但是如果我已經將其聲明爲全局變量,那麼我的警報怎麼會這麼說?undefined

這是一個簡單的例子,但在我的原代碼,我做了很多的東西在函數的開始之間,再長的路下來我檢查,看看是否globalId定義,否則定義它:if(!globalId){var globalId;}這意味着生成我的警報坐落在函數的頂部定義,彷彿JavaScript的第一個執行的整體功能,只是爲了看看是否有任何變量「可能」來聲明,如果是的話,宣佈他們,因此我的警報指出,一個「未申報的」變量。

任何人都可以向我解釋,爲什麼出現這種情況,如果這是真的,JavaScript的執行函數之前的「前宣稱」所有的變量,即使在條件聲明的變量甚至沒有見過面嗎?

+0

+1非常好的問題 – 2013-01-02 12:53:57

+0

局部變量總會有對全球那些precendence。在C和大多數其他語言中是一樣的。在C++中,您可以通過'::'選擇全局變量。無論如何,命名全局變量和局部變量同樣是一種不好的做法 – 2014-05-22 04:03:41

回答

12

在你的代碼的第二部分,局部變量掩蓋了全球性的。

var globalId='10'; 

function check() { 
    // Your are defining a local variable in this function 
    // so, the global one is not visible. 
    alert(globalId); 
    var globalId; 
} 

check(); 


事實上,yopur var聲明是在函數的定義的結束並沒有改變什麼:全局變量是整個函數蒙面

因此,對於功能的整個執行過程中,globalId變量將引用本地一個,而不是全球性的。

該功能之外,雖然,全局變量將仍然存在 - 它只是無法從函數內部可以看到,因爲var聲明。

16

是,在函數的任何位置聲明的所有變量都是局部的功能和整個函數的代碼存在;它們將優先用於同名的全局變量。

https://developer.mozilla.org/en/JavaScript/Guide/Values,_Variables,_and_Literals#Variable_Scope

JavaScript沒有塊語句範圍;相反,它將位於塊所在的代碼的本地位置。 [...] JavaScript中另一個不常見的變量是,您可以引用稍後聲明的變量,而不會發生異常。這個概念被稱爲提升; JavaScript中的變量在某種意義上被稱爲「懸掛」或提升到函數或語句的頂部。

0

您聲明NEW變量globalId函數範圍內,所以它的未定義,這是正確的。不,它不會殺死你的全局變量,你可以在check();調用後加alert(globalId);來檢查它。

22

在javascript中,你應該知道有一種叫做的房源

這實質上意味着什麼,當你聲明任何局部變量時,變量聲明會自動帶到範圍的頂部。

如: -

var globalId='10'; 
function check(){ 
alert(globalId); var globalId; } 
check(); 

更改 -

var globalId='10'; 
function check(){ 
var globalId; 
alert(globalId);} 
check(); 

由於globalID仍然沒有分配任何值,則返回在輸出不確定。局部變量總是優先於全局變量的同名。

+0

首先,感謝您和其他所有人,這麼快就給我提供了有關範圍界定的答案,我不知道所有變量在執行前都移到頂端。但是這裏有一個缺陷,那就是如果我在函數內部聲明變量var globalId =「ABC123」,它仍然會提示未定義。聲明不能移動到頂端,如果那麼我的警報不應該是「ABC123」而不是未定義的?正如我所看到的那樣,Javascript會移動globalid將被聲明的概念,因此在它完成之前無法訪問,因爲它稍後會在代碼中進行訪問......? – 2011-03-31 11:53:34

+7

@per Spjuth - 只有聲明移動到頂部,而不是分配。因此,如果您在警報之前沒有分配,您仍然會得到未定義的值。 – 2011-03-31 11:55:17

0

彷彿第一次的Javascript執行的整體功能,只是爲了看看是否有任何變量「可能」被宣佈

這就是答案,更多或更少。 JavaScript解釋器在每個範圍內查找變量聲明,然後「將它們移動」到範圍的頂部。

+0

Javascript不會執行整個函數,它只是_parses_函數。在實際執行該功能之前,聲明將移至頂端。 – Martijn 2011-03-31 12:15:38

2

如前所述,符合JavaScript範圍規則,局部變量爲整個函數掩蓋了全局。然而,全局變量可以被存取時,請嘗試以下

var globalId='10'; 

function check() { 
    // Your are defining a local variable in this function 
    // so, the global one is not visible. 
    alert('Local : ' + globalId + ', Global : ' + window.globalId); 
    var globalId; 
} 

check(); 
0
var globalId='10'; 
    function check(){ 
     let globalId = '5'; 
     alert(globalId); 

    } 
    check(); 

// use let to set a local variable between any {}