Sau một số điều tra về hành vi của các tuyên bố được gắn nhãn, tôi nghĩ đây thực sự chỉ là sự lựa chọn của Crockford mà không có cơ sở thực tế nào. Theo như tôi có thể nói, không có tình huống nào có thể gây ra xung đột tên với các nhãn trong phạm vi toàn cầu (và đó dường như là lý do chính mà mọi người có thể nghĩ ra vì sao JSLint không cho phép nó - xem nhận xét về câu hỏi).
Các ES5 bang đặc tả sau trong section on labelled statements:
Việc sản xuất Định danh: Báo cáo được đánh giá bằng cách thêm Định danh vào tập nhãn của Tuyên Bố và sau đó đánh giá Tuyên Bố.
...
Trước khi tiến hành đánh giá một LabelledStatement, các chứa Tuyên Bố được coi là sở hữu một bộ nhãn sản phẩm nào, trừ khi nó là một IterationStatement hoặc một SwitchStatement, trong đó trường hợp nó được coi là sở hữu một bộ nhãn bao gồm phần tử đơn, empty
.
Tôi thực hiện điều này có nghĩa là mọi câu lệnh đều có một bộ nhãn. Các mã định danh nhãn là độc lập với các biến số định danh và chức năng, do đó, nó được chấp nhận theo cú pháp để có một nhãn có cùng số nhận dạng như một biến trong cùng một phạm vi.Nói cách khác, đây là hợp lệ:
var label = "My Label";
label:
for (var x = 1; x < 10; x++) {
break label;
}
Vì mỗi tuyên bố đã thiết lập nhãn riêng của mình, điều này cũng là hợp lệ:
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;
}
Vì bạn có thể gắn nhãn bất kỳ tuyên bố (đó là vô nghĩa, nhưng nó có thể) , bạn có thể gắn nhãn một tuyên bố nhãn:
another:
label:
for (var y = 5; y < 15; y++) {
break label;
}
Khi điều này là trường hợp, các quốc gia đặc tả như sau:
Nếu chính sách LabelledStatement có bộ nhãn không trống, các nhãn này cũng được thêm vào bộ nhãn Bản sao kê trước đánh giá nó.
Trong đoạn mã trên, bộ nhãn của câu lệnh for
chứa hai nhãn (another
và label
). Có thể chia nhỏ thành hoặc các nhãn đó từ trong câu lệnh for
.
Và cuối cùng, spec cũng khẳng định (nhấn mạnh thêm):
báo cáo đã được gán nhãn chỉ được sử dụng kết hợp với nhãn break
và continue
báo cáo. ECMAScript không có số goto
tuyên bố.
Vì vậy, dựa trên tất cả những điều đó, tôi không thể nghĩ ra một cách có thể cho bất kỳ nhãn nào trong mã toàn cầu can thiệp vào mã toàn cầu khác. Tất nhiên, rất khó bạn sẽ muốn một chương trình có chứa nhiều nhãn với cùng một mã định danh và JSLint đã ngăn chặn điều đó bằng cách ném một lỗi "nhãn đã được xác định". Nhưng tôi không nghĩ có bất kỳ sự khác biệt nào với cách nó xử lý các câu lệnh có nhãn trong ngữ cảnh thực thi toàn cầu.
Dường như đáng ngờ như biến thể trên "Goto được coi là có hại". –
Tôi thực sự hy vọng điều này không được hỗ trợ trong javascript hiện đại: https://developer.mozilla.org/en/JavaScript/Reference/Statements/label – jbabey
@RobertHarvey - Nó thực sự, nhưng tại sao hành xử khác nhau trong mã toàn cầu? –