2017-04-21 136 views
2

我寫這個簡單的程序來更新JS提升值。但根據我的理解全球x需要更新,但它不更新。全局變量在函數不更新

x = 5; 
var w = function(){ 
    x = 7 
    var x; 
    console.log(x); 
    x = 10; 
    console.log(x); 
}; 
w(); 
console.log(x); 

輸出:

任何人都可以更詳細解釋,它爲什麼沒有更新全局x?

Javascript在值的引用上工作,所以當我寫x = 7時,它應該更新全局x。但它沒有! 所以我只想爲什麼x = 7不起作用?

謝謝!

+0

您在函數內部重新聲明的'x''映射全局函數。 –

+0

嘿,夥計們,我剛剛更新了我的問題。我在js方面有很好的經驗。所以我有關於scopping的想法,我該如何解決這個問題。但我只想知道爲什麼x = 7不更新? –

+0

我在x = 7之後定義了局部x,所以x = 7應該更新全局,然後編譯器移動到下一行。但是x = 7沒有更新全局,這是我主要關心的問題? –

回答

2

因爲您在函數的本地範圍內重新聲明瞭x。這是您爲10指定的地址,而不是全球地址。

var x;它會工作。

x = 5; 
var w = function(){ 
    x = 7 
    // var x; 
    console.log(x); 
    x = 10; 
    console.log(x); 
}; 
w(); 
console.log(x); 

話雖這麼說,有什麼可能莫名其妙你是hoisting

吊裝JavaScript的移動所有聲明在當前範圍的頂部(以當前的腳本或當前的頂部的默認行爲功能)。

x = 5; 
var w = function(){ 
    x = 7 
    var x; // this is moved to the top of the local scope 
    console.log(x); 
    x = 10; 
    console.log(x); 
}; 
w(); 
console.log(x); 
+0

你可以補充你的答案,解釋在Javascript中採用的方式,以及爲什麼在函數內部重新聲明x overrode global x – Lixus

+0

@Lixus你可以通過點擊「編輯」按鈕 - 感覺自由 –

+0

所以你想說,如果我更新任何全局變量在任何函數和任何點之內我定義與全局變量相同的本地變量名稱。那麼全局函數的所有更新都會重置? –

4

你宣佈你的函數內部變量的那一刻,它掩蓋了全局變量,由於道路範圍規則從內工作外。所以,函數級別的var x變量首先被找到,而不是你期望的全局變量。

JS轉換你的函數從:

function(){ 
    x = 7 
    var x; 
    console.log(x); 
    x = 10; 
    console.log(x); 
} 

這樣:

function(){ 
    var x; 
    x = 7 
    //var x; 
    console.log(x); 
    x = 10; 
    console.log(x); 
} 

要將有關更新X = 7,然後宣佈變種X,讓我解釋多一點的問題。 Javascript代碼不只是執行,還有一個編譯階段。在這個階段中,var聲明在函數內部進行了查看(除了發生的其他事情之外,我只是堅持了這個問題)。 如果找到,它們將移到該函數的頂部。這被稱爲提升。在這個時候,你可以認爲你的代碼已經被JS修改了(var聲明和賦值的順序現在無關緊要)。如果你只是想到代碼被解釋,然後順序很重要,但正如我所說,由於彙編階段,吊裝會發生,而不是以這些詞彙來思考會導致你的困惑。一旦你從彙編看起來,提升角度,事情看起來更清晰。

希望它有幫助! 有關進一步研究,請閱讀/聽凱爾辛普森誰是權威的JavaScript。

+0

是的確有。謝謝!。你的回答非常感謝。 –

0

請記住,局部變量的優先級高於其他任何其他變量,並且請使用適當的命名約定來處理全局變量和局部變量,從而避免導致此類錯誤。 他們很難在龐大的項目中被發現。