2012-06-05 49 views
2

我在Sublime Text 2中安裝了Sublimelinter,它很棒。然而,它並不像下面的代碼:在Javascript中的if語句中聲明一個變量是錯誤的嗎?

if(condition){ 
    var result = 1; 
}else{ 
    var result = 2; 
} 
process(result); 

它說,此結果已被定義var result = 2;併爲它的使用超出範圍process(result);。難道僅僅是弄錯if語句的{}一個更封閉的範圍或應我真的會做這樣的:

var result; 
if(condition){ 
    result = 1; 
}else{ 
    result = 2; 
} 
process(result); 
+0

我不會對其他答案提出質疑,但我認爲這是一個壞習慣。var的語義在JavaScript中有點奇怪,當你有條件代碼時它們只會變得很奇怪那。 – Pointy

+1

http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Histing1 – jasssonpet

+0

大閱讀@jasssonpet – Jake

回答

5

不,它不是「錯誤」;按照ECMAScript規範,它將被升至最近的函數定義的頂部。

是的,你的程序「Sublimelinter」聲稱該變量超出範圍是不正確的。

+0

謝謝,這就是我想確認的。我想我更喜歡第二個例子如何讀取。 – Jake

2

這沒有錯。如果您遇到該錯誤,您在代碼中早先定義了result

您還可以簡化您的病情來此,這樣你就不必使用結果:

process(condition ? 1 : 2); 
+0

我需要更快地學習寫作。 ;-) – Oliver

+0

我之前沒有定義'result' - 這只是我的文本編輯器錯誤地判斷if語句是否爲封閉範圍。 – Jake

+0

我喜歡三元運算符的解決方案,但我在概念層面上提出了更多要求,這些示例已經過簡化。 – Jake

0

JavaScript沒有塊範圍。變量的作用範圍與它們所定義的功能有關,這意味着當您在if塊內聲明變量時,它將被「懸掛」到函數頂部。

由於變量在技術上定義在函數的頂部,所以將變量聲明移動到函數的頂部被認爲是一個最佳實踐,以便代碼的意圖清晰。

我想說你的代碼不是「錯誤的」,但它會誤導讀者不熟悉範圍如何在JavaScript中工作的代碼。我肯定會選擇第二個版本,因爲它實際上反映了代碼的執行方式。

Here's a good article解釋變量提升。

0

聲明你的var指針一次 - 在你有if語句的函數中。就像ninjagecko提到的,所有的變量都被髮送到它們包含的函數的頂部。

但是;請小心,因爲如果你像聲明一樣聲明兩次相同的變量,它將重置變量。

0

我建議這樣做:

var result = MORE_LIKELY_OUTCOME; 

if (LESS_LIKELY_CONDITION) { 
    result = LESS_LIKELY_OUTCOME; 
} 

process(result); 

這樣,你最初設定的結果是什麼,你都希望它是大部分的時間。 然後,如果條件發生,則if語句將更改結果。

1

與其他許多語言一樣,Javascript沒有「塊範圍」。如果是這樣,當您嘗試呼叫process(result)時,變量result將不存在,因爲它不可能在定義它的{}塊之外引用它。

但是,JavaScript只有函數範圍,其中一個函數中的變量不能被另一個函數訪問。在函數中聲明變量沒有任何意義,因爲它仍然可以從該函數中的任何地方訪問(無塊範圍)。因此,您發佈的兩個代碼片段都等同於任何解釋器運行代碼。

第二個是可取的,因爲它更清晰,因爲它顯示了變量將被使用的位置(整個函數)。它還可以防止變量在函數的範圍內被聲明兩次,這可能不一定會導致任何不好的事情發生,但它絕對不會造成任何好處。您應該幾乎總是在較高級別聲明一個變量,而不是在兩個不同的較低級別聲明變量,即使它並不重要,因爲變量的範圍將是整個函數,無論聲明在哪裏。

0

事實證明,SublimeLinter正在使用JSHint,它可以選擇抑制此警告並解釋它存在的原因。


funcscope此選項禁止有關聲明變量 控制結構的內部,而從外面 後來訪問這些警告。儘管JavaScript只有兩個實際範圍 - 全局函數和功能 - 這種實踐導致新手語言和難以調試的錯誤之間的混淆。這樣,默認情況下,JSHint會警告 關於在其預期範圍之外使用的變量。

相關問題