JavaScript의 구문 분석 8 진 동작을 어떻게 해결합니까?


283

JavaScript에서 다음을 실행하십시오.

parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!

난 그냥 자바 스크립트가 앞에 0이 표시 생각하는 것을 어렵게 배운 진수 정수를 , 더 있기 때문에 "8"또는 "9"기본-8, 함수는 0을 반환하지합니다. 좋든 싫든, 이것은 의도적으로 설계된 것 입니다.

해결 방법은 무엇입니까?

참고 : 완전성을 위해 솔루션을 게시하려고하지만 싫어하는 솔루션이므로 다른 답변을 게시하십시오.


최신 정보:

자바 스크립트 표준 5 판 ( ECMA-262 )에는이 동작을 제거하는 주요 변경 사항이 도입되었습니다. 모질라는 글을 잘 쓴다 .


21
1 단계) 자신에게 유리한 태도를 취하고 Doug의 책뿐만 아니라 이전 답변에서 언급 한 기수를 항상 포함하십시오. 2 단계) JavaScript 학습에 대해 진지한 경우 Doug의 책을 구하십시오. 귀중합니다. 지금까지 나의 즐겨 찾기 책. 여기 리뷰는 참고하시기 바랍니다있다 : realtech.burningbird.net/learning-javascript/basics/...
fuentesjr

8
Internet Explorer 9와 같은 ECMAScript 5th Edition 호환 브라우저에서 10구문 분석 할 숫자 앞에라는 접두사가 붙지 않는 한 기본 매개 변수의 기본값은 10 진수입니다 0x(예 : 0xFF기본 매개 변수의 기본값은 16 임). 먼 기억 일 것입니다.
Andy E

2
어때요 +'08' === 8? 진실! 어쩌면 parseInt실제 코드 가 필요할 수도 있지만 위의 코드는 필요 하지 않습니다.
kojiro

1
a) 이것은 버그가 아닙니다. 제목을 수정하십시오. b)Number('08')
OnTheFly

4
@portman : "제 5 판은 ...을 제거해이 동작하는 주요 변경을 소개합니다" (십삼년 전)도 3 판에서 것을 아마 가치가 포인팅, 구현은 그것을 할 수 없습니다 "격려"하고 "기수 인 경우 0또는 undefined문자열의 숫자는 또는 0뒤에 오는 숫자가 아닌 숫자로 시작하며 , 구현은 임의로 재량에 따라 숫자를 8 진수 또는 10 진수로 해석 할 수 있습니다. 이 경우 숫자를 10 진수로 해석하도록 권장됩니다. "xX ( 나의 강조점)
TJ Crowder

답변:


329

이것은 간단한 해결책을 가진 일반적인 자바 스크립트입니다.

다음과 같이 base 또는 'radix'를 지정하십시오 .

parseInt('08',10); // 8

Number 를 사용할 수도 있습니다 .

Number('08'); // 8

57
. 거룩한.
포트만

10
Number는 08 주위에 따옴표가 필요합니다. 또한 그냥 경고하면, Number ('08 .123 ')는 출력으로 8.123을 생성합니다. 정수를 정말로 원한다면 숫자를 사용하지 마십시오 (또는 정수만 보장하기 위해 입력과 패턴 일치).
Jason S

3
번호 (08); Firefox와 IE에서 8을 제공합니다.
Paolo Bergantino

3
ECMAscript 표준의 일부가 아닙니다. Spidermonkey 1.7 (= Firefox JS 엔진)을 사용하는 JSDB에서 테스트 중이며 "08은 유효한 ECMA-262 8 진 상수가 아닙니다"
Jason S

5
여전히 따옴표로 '08'을 사용하십시오. 08은 ECMA-262 표준을 준수하지 않으며 경고 및 / 또는 오류 및 / 또는 지정된 특정 동작없이 성공을 보장하지 않습니다.
Jason S

43

값이 부호있는 32 비트 정수 범위에 있음 을 알고 있으면 ~~x모든 시나리오에서 올바른 작업을 수행합니다.

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1

이진 ( ~)을 찾지 않으면 스펙은 Int32 로의 명백한 변환을 수행하고 NaN값을 0 으로 강제하도록 지정된 인수에 대해 "ToInt32"변환이 필요합니다 .

예, 이것은 엄청나게 해킹 적이지만 매우 편리합니다 ...


2
하나의 바이너리 또는 충분할 때 왜 두 개의 작업이 필요한가?
Oleg V. Volkov

@ 올렉, 왜 충분할까요?
Sebastian

3
@SebastianGodelet, | 0.
Oleg V. Volkov 2014 년

@Grodriguez, | 0의 0이 문자열 인 경우?
Oleg V. Volkov

이 전체 질문은 문자열을 정수로 변환하기위한 parseInt의 대안에 관한 것입니다. 따라서 : 항상.
Grodriguez

24

로부터 으로 parseInt 문서 , 밑이 10 인 지정 옵션 기수 인수를 사용합니다 :

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9

이것은 나를 혼란스럽고 혼란스럽고 장황하게 표현합니다 (실제로 모든 단일 구문 분석에서 추가 인수입니까?).


6
Verbosity가 마음에 들지 않으면 내장 함수를 호출하고 인수를 채우는 고유 한 함수를 만들어 항상 일정하게 유지하십시오.
Jason S

3
Riiiiiiight는 StackOverflow의 모든 사람이 parseIntB10 함수를 작성하는 데 속도를 낼 수있는 것은 아닙니다. 자신 만의 래퍼 함수를 ​​작성하는 것은이 목적을위한 끔찍한 아이디어입니다.
Stefan Kendall

2
@iftrue : 당신이 내 요점을 놓쳤다 고 생각합니다. 개인적으로 parseInt (someString, 10)을 수행하여 기본 10을 강제로 수행하도록 신경 쓰지 않습니다. OP는이 접근법을 좋아하지 않는 것처럼 보이므로 개인적으로 사용하지 않지만 아마도 그의 요구를 충족시키는 대안을 제안했습니다. 필요합니다. (이것은 분명히 JQuery의 생각입니다. 복잡성을 추가하여 편리하게 만듭니다. JQuery를 사용하지 않지만 많은 사람들이 유용하다고 생각합니다.)
Jason S

4
사실 그것은 포장 정말 중요한 parseInt것처럼, 기능적 표현에 편리하게 사용할 수 map있는 ["7","4","09","5"].map(parseInt); Map패스됩니다 인덱스 에 의해 해석됩니다 두 번째 인수로 배열의 요소를 parseInt당신이 그것을 포장하지 않는 한 기본으로.
Plynx

11
function parseDecimal(s) { return parseInt(s, 10); }

편집 : 당신이 정말로 원하는 것을하기 위해 자신의 함수를 만드는 것은 parseInt () 호출에 항상 ", 10"을 추가하고 싶지 않다면 옵션 일뿐입니다. 비표준 기능이라는 단점이 있습니다. 많이 사용하면 더 편리하지만 다른 사람들에게는 더 혼란 스럽습니다.


10

베이스를 지정하십시오.

var number = parseInt(s, 10);

와우 너희들은 빠르다. 나는 클립 보드에 대답을했다. 네오 스타일 인터넷에 직접 연결되어 있습니까?
포트만

1
악마가 왜베이스 (10)에 기본값 없습니다
톰 Gullen

2
어쩌면 그것은 주로 문자열-> 숫자 변환 함수를 의미하는 것이 아니라 기본 b 숫자 문자열에서 숫자를 읽는 함수이기 때문일 수 있습니다.
artistoex

2
기본 10으로 설정되지만 선행 0은 8 진을 나타내는 광범위한 방법입니다.
Nathan

7

parseInt에 두 번째 매개 변수가 없으면 십진수로 가정하는 버전으로 바꾸는 것이 매우 좋지 않을까요? (참고-테스트되지 않음)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}

2
그렇습니다, 그것은 나쁜 것입니다-표준 행동에 의존하는 다른 코드를 깨뜨릴 것입니다.
jes5199

4
사실이지만 그다지 많지 않습니다. 또한 표준 동작이 아닙니다. 8 진 지원은 선택 사항입니다.
Andrew Duffy

2
그러나 옵션이 아닌 16 진수 지원을 중단하고 있습니까? 이것은 항상 사실이어야합니다 : parseInt("0xFFFFFF") === 16777215,하지만 당신의 장난 꾸러기 해킹으로 더 이상 작동하지 않습니다parseInt("0xFFFFFF") === 0
Timo


6

parseFloat 또는 parseInt를 사용하는 대신 단항 연산자 ( + )를 사용할 수도 있습니다.

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

그리고 좋은 측정을 위해

+"09.09"
// => 9.09

MDN 링크

단항 더하기 연산자는 피연산자 앞에 오며 피연산자로 평가되지만 숫자가 아닌 경우에는 피연산자로 변환하려고 시도합니다. 단항 부정 (-)도 숫자가 아닌 숫자를 변환 할 수 있지만, 단항 더하기는 숫자 에서 다른 연산을 수행하지 않기 때문에 무언가를 숫자로 변환하는 가장 빠르고 선호되는 방법입니다 .


5

십진법은 어떻습니까?

('09'-0) === 9  // true

('009'-0) === 9 // true

4

parseInt로 이미 많은 코딩을 수행했고 모든 것에 ", 10"을 추가하고 싶지 않은 경우, 기본 10을 기본값으로 설정하기 위해 함수를 재정의하면됩니다.

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

나중에 독자에게 혼란을 줄 수 있으므로 parseInt10 () 함수를 만드는 것이 더 자명 할 수 있습니다. 개인적으로 나는 항상 ", 10"을 추가하는 것보다 간단한 기능을 사용하는 것을 선호합니다-실수의 기회를 더 많이 만듭니다.


0

이 문제는 최신 Chrome 또는 Firefox (2019)에서 복제 할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.