在對有標籤的陳述的行爲進行了一些調查之後,我認爲這實際上只是Crockford的一個選擇,實際上並沒有真正的基礎。據我所知,沒有任何情況可能導致與全球範圍內的標籤發生命名衝突(這似乎是人們可能會想到爲什麼JSLint不允許它的主要原因 - 請參閱有關問題的評論)。
的ES5規範規定在section on labelled statements如下:
生產標識符:語句通過添加 標識符的標籤組聲明,然後評估聲明評估。
...
此前有LabelledStatement,所包含的聲明的評價,應視爲具有空標籤組,除非它是一個IterationStatement或SwitchStatement,其中如果它被視爲擁有由單個元素組成的標籤集,則爲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
的語句包含兩個標籤(another
和label
)。有可能在for
語句中打破這些標籤的。
最後,該規範還規定(強調):
標記語句只能配合使用標記break
和continue
語句。 ECMAScript沒有goto
陳述。
所以基於這一切,我想不出任何標籤在全局代碼中干擾其他全局代碼的可能方式。當然,你不可能想要一個包含多個具有相同標識符的標籤的程序,並且JSLint已經通過拋出「已定義標籤」錯誤來阻止該標籤。但我不認爲它應該如何在全局執行上下文中處理帶標籤的語句。
它看起來很可疑,就像「Goto認爲有害」的變體一樣。 – 2012-07-17 20:39:57
我真的希望這不是現代javascript支持:https://developer.mozilla.org/en/JavaScript/Reference/Statements/label – jbabey 2012-07-17 20:43:40
@RobertHarvey - 確實,但爲什麼在全局代碼中表現不同? – 2012-07-17 20:45:57