2016-11-10 51 views
5

我在玩一些代碼,遇到了一種情況,我無法確定爲什麼'let'的行爲是這樣。let關鍵字問題

對於以下代碼塊:

var x = 20; // global scope 
 

 
function f() { 
 
    let x = x || 30; 
 
} 
 

 
f(); // VM3426:1 Uncaught ReferenceError: x is not defined(…)

我得到的錯誤上執行F 'x被沒有定義'()。我明白「讓」變量不會被提升,但是因爲'x'有全局副本,爲什麼函數'f'中的行不是全局副本而是拋出錯誤? 在函數的開頭,'let'是否設置變量未聲明(而不是由於提升引起的'未定義'var)? 有沒有辦法在函數中獲取'x'的全局副本?

+0

的[「讓」的關鍵字與「VAR」可能的複製關鍵字在Javascript](http://stackoverflow.com/questions/762011/let-keyword-vs-var-keyword-in-javascript) – ozil

+1

本地'x'的聲明是陰影的全球之一,但你是根據現有的'x'分配一個值,compliler ca沒有找到一個像一個是被遮蔽的,另外一個還沒有被宣佈。 –

回答

5

唯一的例外是關於右側X - 當你初始化塊範圍X可變全球一個已經「遺忘」,然而新一仍然沒有被宣佈,並在無法使用初始化

有明確呼籲全球一個

function f() { 
     let x = window.x || 30; 
    } 

而且看看this MDN article比較約死區

+1

所以你所說的是這部分'let x'首先被計算,局部變量'x'被創建但沒有被聲明(這樣全局x被映射),然後這個部分被執行。沒有找到30'和'x'? –

+0

是的 - 這就是發生了什麼 –

+0

謝謝,我想知道這個過程'創建,但沒有聲明'被稱爲 –

0

允許您將範圍受限的變量聲明爲使用它的塊,語句或表達式。這與var關鍵字不同,該關鍵字在全局範圍內定義變量,或者在本地定義整個功能,而不考慮塊範圍。

在你的情況下,拋出一個異常是因爲你定義了let的同名。

For More Info

+0

這應該不是問題,在函數內部它應該使用'let' x,在'var'之外 –

0

局部x的聲明陰影全局的和新的還沒有宣佈第一和初始化過程中不能使用。這是同樣的情況類似以下內容:

var foo = 5; 
    function do_something() { 
     console.log(foo); // ReferenceError 
     let foo = 2; 
    } 
    do_something(); 

僅供參考MDN

至於建議由@ m.antkowicz你可以在你的情況下使用window.x