2015-10-16 20 views
0

變量所以,我偶然發現了這種行爲JavaScript的提升來自未執行分支

var foo = "bar"; 

(function(){ 
    if(false) { 
     var foo = "this truns the variable to undefined"; 
    } 
    console.log(foo); // => undefined 
})(); 

我理解提升的概念。但是,不應該只在分支執行時纔會發生?

var foo = "bar"; 

(function(){ 
    if(false) { 
     foo = "this scenario is just fine"; 
    } 
    console.log(foo); // => "bar" 
})(); 
+1

沒有。它不管執行情況如何。 –

+0

你是什麼意思的「預設?」舊IE中的 –

+0

是的,在較新的瀏覽器中沒有。相同的功能語句btw ... – dandavis

回答

2

由於可變懸掛和本地聲明的變量隱藏了同名的全局變量的事實,你的代碼第一塊是相同的:

var foo = "bar"; 

(function(){ 
    // define new local variable foo that hides the global one 
    var foo; 
    if(false) { 
     foo = "this truns the variable to undefined"; 
    } 
    console.log(foo); // => undefined, local foo has not been assigned a value 
})(); 

由於吊裝,該變量無論函數內的執行路徑如何,都在函數塊的開始處定義。用var聲明的變量作用於整個函數,函數中的所有定義都被提升到函數的頂部。

使用let(ES6功能)定義的變量的作用域爲聲明它們的塊(仍然懸掛在塊的頂部),但它們的定義僅限於聲明它們的塊,而不是函數在那裏他們宣佈。因此,如果您使用let而不是var,則會得到不同的結果。

因此,在您的第一個代碼塊中,您將在函數的開頭聲明一個新變量foo,並且新聲明將隱藏全局定義的相同名稱,以便該函數內的任何對foo的引用都將引用到當地的一個。

條件if陳述僅影響foo的分配,而不影響foo的聲明。因此,如果if語句未執行,則fooundefined,因爲它從未分配過值。


在你的第二個代碼塊,沒有新的本地foo變量定義所以foo所有引用都只是指全球foo以來沒有新的變量聲明,也沒有提升。第二個代碼塊的行爲非常符合IIFE函數是否存在 - 這只是一個簡單的if語句,用於決定是否更改全局foo的值。

+0

「用var聲明的變量被限定爲整個函數,函數中的所有定義都被提升到函數的頂部。」這解釋了一切。交換var讓我們確認一下。謝謝 – alknows