2012-04-01 54 views
0

我有以下代碼:關於VAR聲明JavaScript的行爲解釋

"use strict"; 

function isDefined(variable) 
{ 
    return (typeof (window[variable]) === "undefined") ? false : true; 
} 

try 
{ 
    isDefined(isTrue); 
} 
catch (ex) 
{ 
    var isTrue = false; 
} 

isTrue = true; 

可有人請向我解釋爲什麼當我刪除關鍵字「變種」我得到拋出的異常,但是當它是有它對待它像未定義?

+0

兩件事情你可能要考慮:'返回的typeof窗口[變量] ==「未定義」;'就足夠了,isDefined的有效簽名'isDefined(字符串)',這意味着'isDefined('isTrue')'得到你期望的行爲('window [undefined]','window [true]'和'win dow [false]'沒有意義)。 – Bergius 2012-04-01 10:12:35

回答

3

以嚴格模式運行時,不允許訪問先前未聲明的變量。因此,isTrue必須先聲明才能訪問它。因此,如果您刪除前面的var,並且沒有在其他地方聲明它,那將是一個錯誤。

MDN page on strict mode報價:

首先,嚴格的模式使得它不可能意外地創建全球 變量。在正常的JavaScript中,如果忽略了賦值 中的變量,將會在全局對象上創建一個新屬性,並繼續「工作」 (儘管未來可能失敗:可能在現代JavaScript中)。 分配這將意外地而不是扔在嚴格模式 創建全局變量:

你的問題的一部分約undefined是一個比較複雜的。由於可變懸掛在那裏聲明一個變量被編譯器提升到它的聲明中範圍的頂部,與var聲明你的代碼是相同的:

var isTrue; 
try 
{ 
    isDefined(isTrue); 
} 
catch (ex) 
{ 
    isTrue = false; 
} 

isTrue = true; 

因此,當你調用isDefined(isTrue),值的isTrueundefined。它已被聲明,但未初始化,因此它的值爲undefined。如果您沒有var語句,則在嚴格模式下對isTrue的任何引用都是錯誤的,因爲它尚未聲明。

如果你只是想知道,如果一個變量的值呢,你可以簡單地這樣做:

if (typeof isTrue != "undefined") { 
    // whatever code here when it is defined 
} 

或者,如果你只是想確保它有一個值,如果它有沒有被初始化,你可以這樣做:

if (typeof isTrue == "undefined") { 
    var isTrue = false; 
} 
+0

「由於編譯器將變量聲明掛起到聲明範圍的頂部,所以變量掛起」;「這對所有尊重ECMA5的瀏覽器都適用嗎?使用此代碼在舊版瀏覽器上會發生什麼? – 2012-04-01 09:50:57

+0

@RandallFlagg - 提升一直是javascript的一部分 - 它不是ECMA5的新功能,因此所有瀏覽器都可以進行可變提升。與嚴格模式的區別在於,分配給未聲明的變量是一個錯誤,而在較早的瀏覽器中,它會自動根據該名稱創建一個全局變量。 – jfriend00 2012-04-01 09:51:54