019가 JavaScript 구문 오류가 아닌 이유는 무엇입니까? 또는 019> 020 인 이유


78

019 > 020JavaScript 콘솔 (Chrome과 Firefox에서 테스트 됨)에 입력 하면 대답을 얻습니다 true.

이것은 때문이다 020으로 해석되고 OctalIntegerLiteral(등호 16반면에) 019분명히으로 해석되고있다 DecimalLiteral(와 동일 19). 으로 19보다 큰 16, 019 > 020이다 true.

나를 당혹스럽게 019하는 DecimalLiteral것은 처음으로 해석되는 이유 입니다 . 어떤 생산입니까? DecimalIntegerLiteral허용하지 않음 019:

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt

OctalIntegerLiteral또한 허용하지 않습니다 019( 98 진수가 아니므로) :

OctalIntegerLiteral ::
    0 OctalDigit
    OctalIntegerLiteral OctalDigit

OctalDigit :: one of
    0 1 2 3 4 5 6 7

그래서 제가 사양에서 본 019것은 실제로 거부되어야합니다. 왜 그것이 십진 정수로 해석되는지 모르겠습니다.

여기에 어떤 종류의 호환성 규칙이 있다고 생각하지만 공식적인 정의를 찾지 못했습니다. 누구든지 이것으로 나를 도울 수 있습니까?

(이것이 필요한 이유 : JavaCC를 사용하여 Java 용 JavaScript / ECMAScript 파서를 개발 중이며 사양 및 그 편차에 특별한주의를 기울여야합니다.)


3
019 + 0 == 19그리고 020 + 0 == 17이 아닌 8 진수가 포함 된 경우 그래서 앞의 0을 무시합니다.
Reactgular

22
재미있는 사실 : 'use strict'; 019→ SyntaxError : 8 진 리터럴과 8 진 이스케이프 시퀀스는 더 이상 사용되지 않습니다
goto-bus-stop

4
@Mathew : 확실히 020 + 0 ≠≠ 17:)
Jongware

4
@Mouser : 같은 것이 아닙니다. parseInt는 첫 번째 유효하지 않은 문자에서 멈 춥니 다.
Jongware

2
@FelixKling 그것이 생산이 공식화되는 방법이기 때문입니다. 어느 0NonZeroDigit DecimalDigits_opt. 0뒤에 어떤 것이 있으면 DecimalIntegerLiteral더 이상 아닙니다 .
lexicore

답변:


52

내가 찾은 바에 따르면 JavaScript의 일부 구현은 해당 지점의 사양을 따르지 않는 것 같습니다.

로부터 MDN 사이트 :

십진 리터럴은 영 (0)과 다른 십진수로 시작할 수 있지만 선행 0 뒤의 다음 숫자가 8보다 작 으면 숫자가 8 진수로 구문 분석됩니다. 이것은 JavaScript에서 발생하지 않습니다 . bug 957513을 참조하십시오 . parseInt ()에 대한 페이지도 참조하십시오.

이것은 019 == 19선행 0 뒤의 다음 숫자가 1이고 따라서 전체 숫자를 8 진수로 구문 분석해야하는 이유를 설명하지 않습니다 . 그러나 참조 된 버그는 귀하의 사례와 관련이있는 것 같습니다. 설명은 다음과 같습니다.

다음 JavaScript 프로그램은 오류를 발생시켜야합니다.

08

사양에 따라 Chrome / Opera, PrestOpera 및 Firefox에서 지원하지만 다른 십진수 DecimalIntegerLiteral0바로 뒤에 올 수 없습니다 .

버그는 WONTFIX로 종료되었습니다.

그러나 019다음 버전의 초안에 따르면 값이 19 인 유효한 십진수 리터럴이됩니다.

https://people.mozilla.org/~jorendorff/es6-draft.html#sec-additional-syntax-numeric-literals

(관련 규칙을 표시했습니다)

The syntax and semantics of 11.8.3 is extended as follows except that 
this extension is not allowed for strict mode code:

[...]

DecimalIntegerLiteral ::
    0
    NonZeroDigit DecimalDigits_opt
    NonOctalDecimalIntegerLiteral                         // (1)

NonOctalDecimalIntegerLiteral ::
    0 NonOctalDigit
    LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit    // (2)
    NonOctalDecimalIntegerLiteral DecimalDigit

LegacyOctalLikeDecimalIntegerLiteral ::
    0 OctalDigit                                          // (3)
    LegacyOctalLikeDecimalIntegerLiteral OctalDigit

그래서 01A는 LegacyOctalLikeDecimalIntegerLiteral(3). 그러면 019A는 NonOctalDecimalIntegerLiteral차례로 (2) DecimalIntegerLiteral(1).


2
이것이 정답입니다. Chrome에도 비슷한 문제가있는 것 같습니다. 019Spidermonkey로 평가 하면 1: warning: 09 is not a legal ECMA-262 octal constant: 019. 기존의 (중요한) 사이트가 망가질 것이기 때문에 철회 된 것 같습니다.
Felix Kling

2
019두 번째 숫자가 1? 라고해서 왜 8 진수 리터럴이 될 것으로 예상하는지 잘 모르겠습니다 . 포함 확실히 아무것도 9... 진수가 될 수 없습니다
BERGI

2
@Bergi 나는이 해석을 정당화하는 ECMAScript 사양에서 어떤 점도 찾을 수 없었기 때문에 MDN의 사람들에게 물어봐야한다고 생각합니다.
abl

4
V8 구문 분석 스캐너를 살펴보면 실제로 숫자가 0으로 시작하지만 숫자 8 또는 9가있는 경우 숫자는 십진수라고 가정합니다 (이유를 설명하는 주석은 없습니다) github.com/v8/v8/blob/97757e2d8c5b706f1f642340a424b38e20022a2c/ ...
Vitalii Fedorenko

2
@VitaliiFedorenko 당신이 그것을 파낸 방법에 매우 감동했습니다.
lexicore
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.