2012-07-17 14 views
8

我只是瀏覽source of JSLint,發現這段代碼:在全局代碼中使用帶標籤的語句有什麼問題?

// Is this a labeled statement? 
//... 
if (next_token.labeled !== true || funct === global_funct) { 
    stop('unexpected_label_a', label); 
} //... 

有趣的部分是funct === global_funct比較。貫穿的JSLint下面的代碼片段拋出一個「意外的標籤」錯誤,因爲該標記語句是在全局執行環境(我知道,這是一個愚蠢的例子Here's a fiddle。):

loop: 
for (var i = 0; i < 10; i++) { 
    if (i === 5) { 
     break loop; 
    } 
} 

如果你把同樣的代碼片段在一個函數中,JSLint完全滿意它,並且在遇到標籤時不會拋出錯誤。帶有將通過JSLint的代碼的Here's a fiddle。如果你想嘗試,代碼可以粘貼到online version of JSLint

所以我的問題:在全局代碼中使用帶標籤的語句有什麼問題,或者它只是Crockford的另一個人選擇?

+0

它看起來很可疑,就像「Goto認爲有害」的變體一樣。 – 2012-07-17 20:39:57

+0

我真的希望這不是現代javascript支持:https://developer.mozilla.org/en/JavaScript/Reference/Statements/label – jbabey 2012-07-17 20:43:40

+0

@RobertHarvey - 確實,但爲什麼在全局代碼中表現不同? – 2012-07-17 20:45:57

回答

3

在對有標籤的陳述的行爲進行了一些調查之後,我認爲這實際上只是Crockford的一個選擇,實際上並沒有真正的基礎。據我所知,沒有任何情況可能導致與全球範圍內的標籤發生命名衝突(這似乎是人們可能會想到爲什麼JSLint不允許它的主要原因 - 請參閱有關問題的評論)。

的ES5規範規定在section on labelled statements如下:

生產標識符:語句通過添加 標識符的標籤組聲明,然後評估聲明評估。

...

此前有LabelledStatement,所包含的聲明的評價,應視爲具有空標籤組,除非它是一個IterationStatementSwitchStatement,其中如果它被視爲擁有由單個元素組成的標籤集,則爲empty

我認爲每個語句都有一個標籤集。標籤標識符與變量和函數標識符無關,所以在語法上可以接受的是,在同一範圍內具有與變量標識符相同的標籤。換句話說,這是有效的:

var label = "My Label"; 
label: 
for (var x = 1; x < 10; x++) { 
    break label; 
} 

由於每個語句都有自己的標籤集,這也是正確的:

label: 
for (var x = 1; x < 10; x++) { 
    //Looks for 'label' in label set of `break` statement, then `for` statement 
    break label; 
} 
label: 
for (var y = 5; y < 15; y++) { 
    //Same again. Will never look for label outside the enclosing `for` statement 
    break label; 
} 

既然你可以標記任何聲明(這是毫無意義的,但有可能) ,你可以標記一個標記聲明:

another: 
label: 
for (var y = 5; y < 15; y++) { 
    break label; 
} 

如果是這種情況,該規範規定如下:

如果標註語句本身具有非空標籤集,則在對 進行評估之前,還會將這些標籤添加到Statement的標籤集。

在上面的代碼中,標籤設置for的語句包含兩個標籤(anotherlabel)。有可能在for語句中打破這些標籤的

最後,該規範還規定(強調):

標記語句只能配合使用標記breakcontinue語句。 ECMAScript沒有goto陳述

所以基於這一切,我想不出任何標籤在全局代碼中干擾其他全局代碼的可能方式。當然,你不可能想要一個包含多個具有相同標識符的標籤的程序,並且JSLint已經通過拋出「已定義標籤」錯誤來阻止該標籤。但我不認爲它應該如何在全局執行上下文中處理帶標籤的語句。