2012-07-17 3 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는 완벽하게 만족하며 레이블을 만났을 때 오류를 던지지 않습니다. Here's a fiddle에는 JSLint를 전달하는 코드가 있습니다. 시도하려는 경우 코드를 online version of JSLint에 붙여 넣을 수 있습니다.

내 질문 : 전역 코드에서 레이블이있는 명령문을 사용하는 데 문제가 있습니까? 아니면 Crockford의 또 다른 개인적인 선택입니까?

+0

"Goto가 유해하다고 생각합니다."라는 변형이 의심스러워 보입니다. –

+0

나는 이것이 현대 자바 스크립트에서 지원되지 않기를 바란다 : https://developer.mozilla.org/en/JavaScript/Reference/Statements/label – jbabey

+0

@RobertHarvey - 실제로 그렇지만 왜 글로벌 코드에서 다르게 행동 하는가? –

답변

3

레이블이 지정된 명령문의 동작을 조사한 결과 실제로 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; 
} 

:

, 당신은 레이블 문에 레이블을 지정할 수 있습니다 0

LabelledStatement 자체에 비어 있지 않은 레이블 집합이있는 경우 이러한 레이블은 을 평가하기 전에 명세서의 레이블 집합에도 추가됩니다. 위의 코드에서

for 문 세트 라벨은 두 개의 레이블 ( anotherlabel)가 포함되어 있습니다. for 문 내에서 의 레이블을 개로 분리 할 수 ​​있습니다.

그리고 마지막으로, 투기도 상태 (강조 추가)

표기 문은 표지 breakcontinue 문장과 함께 사용된다. ECMAScript에는 goto이 없습니다.

따라서 나는 글로벌 코드의 모든 레이블이 다른 글로벌 코드를 방해 할 수있는 방법을 생각할 수 없습니다. 물론 동일한 식별자를 가진 여러 레이블을 포함하는 프로그램을 원할 가능성은 매우 낮습니다. JSLint는 이미 "레이블이 이미 정의되어 있습니다"라는 오류를 던져서이를 방지합니다. 그러나 전역 실행 컨텍스트에서 레이블이 지정된 문을 처리하는 방법과 어떤 차이가 있어야한다고 생각하지 않습니다.

관련 문제