parseInt가 Array # map으로 NaN을 생성하는 이유는 무엇입니까?
로부터 모질라 개발자 네트워크 :
[1,4,9].map(Math.sqrt)
산출 할 것이다 :
[1,2,3]
그렇다면 왜 이렇게합니까?
['1','2','3'].map(parseInt)
이것을 산출하십시오 :
[1, NaN, NaN]
Firefox 3.0.1 및 Chrome 0.3에서 테스트했으며 면책 조항처럼 이것이 브라우저 간 기능이 아니라는 것을 알고 있습니다 (IE 없음).
나는 다음이 원하는 효과를 얻을 것이라는 것을 알았습니다. 그러나 여전히의 잘못된 동작을 설명하지는 않습니다 parseInt
.
['1','2','3'].map(function(i){return +i;}) // returns [1,2,3]
의 콜백 함수 Array.map
에는 세 가지 매개 변수가 있습니다.
링크 한 동일한 Mozilla 페이지 에서 :
콜백은 요소의 값, 요소의 색인 및 순회되는 Array 객체의 세 가지 인수로 호출됩니다. "
따라서 parseInt
실제로 두 개의 인수를 예상 하는 함수를 호출하면 두 번째 인수는 요소의 색인이됩니다.
이 경우 parseInt
기수 0, 1 및 2로 차례로 전화 를 걸었 습니다 . 첫 번째는 매개 변수를 제공하지 않는 것과 동일하므로 입력 (이 경우 10 진법)을 기준으로 기본값이 설정됩니다. 기수 1은 불가능한 수 기수이며 3은 기수 2에서 유효한 숫자가 아닙니다.
parseInt('1', 0); // OK - gives 1
parseInt('2', 1); // FAIL - 1 isn't a legal radix
parseInt('3', 2); // FAIL - 3 isn't legal in base 2
따라서이 경우 래퍼 함수가 필요합니다.
['1','2','3'].map(function(num) { return parseInt(num, 10); });
또는 ES2015 + 구문으로 :
['1','2','3'].map(num => parseInt(num, 10));
(두 경우 모두 입력에 따라 기수를 추측하기 때문에 그림과 같이 기수 를 명시 적으로 제공하는 것이 가장 좋습니다 parseInt
. 일부 구형 브라우저에서는 선행 0을 사용하면 8 진을 추측하게되어 문제가되었습니다. 문자열이로 시작하면 16 진수를 추측하십시오 0x
.)
map
는 많은 인수에서 parseInt
기수 매개 변수를 엉망으로 만드는 두 번째 인수를 전달 합니다.
밑줄을 사용하는 경우 다음을 수행 할 수 있습니다.
['10','1','100'].map(_.partial(parseInt, _, 10))
또는 밑줄없이 :
['10','1','100'].map(function(x) { return parseInt(x, 10); });
iteratee 함수로 Number 를 사용하여이 문제를 해결할 수 있습니다.
var a = ['0', '1', '2', '10', '15', '57'].map(Number);
console.log(a);
새 연산자가 없으면 Number를 사용하여 유형 변환을 수행 할 수 있습니다. 그러나 parseInt와 다릅니다. 문자열을 구문 분석하지 않고 숫자를 변환 할 수 없으면 NaN을 반환합니다. 예를 들어 :
console.log(parseInt("19asdf"));
console.log(Number("19asf"));
parseInt의 두 번째 매개 변수 인 기수와 관련하여 펑키 한 것입니다. Array.map을 사용하여 왜 깨뜨리고 직접 호출 할 때가 아닌지 모르겠습니다.
// Works fine
parseInt( 4 );
parseInt( 9 );
// Breaks! Why?
[1,4,9].map( parseInt );
// Fixes the problem
[1,4,9].map( function( num ){ return parseInt( num, 10 ) } );
화살표 기능 ES2015 / ES6을 사용하고 숫자를 parseInt에 전달하면됩니다. 기수의 기본값은 10입니다.
[10, 20, 30].map(x => parseInt(x))
또는 코드의 가독성을 높이기 위해 기수를 명시 적으로 지정할 수 있습니다.
[10, 20, 30].map(x => parseInt(x, 10))
위의 기수에서 명시 적으로 10으로 설정
또 다른 (작동) 빠른 수정 :
var parseInt10 = function(x){return parseInt(x, 10);}
['0', '1', '2', '10', '15', '57'].map(parseInt10);
//[0, 1, 2, 10, 15, 57]
parseInt
이러한 이유로 IMHO는 피해야합니다. 다음과 같은 상황에서 더 안전하게 만들기 위해 랩핑 할 수 있습니다.
const safe = {
parseInt: (s, opt) => {
const { radix = 10 } = opt ? opt : {};
return parseInt(s, radix);
}
}
console.log( ['1','2','3'].map(safe.parseInt) );
console.log(
['1', '10', '11'].map(e => safe.parseInt(e, { radix: 2 }))
);
lodash / fp는 이러한 문제를 피하기 위해 기본적으로 반복 인수를 1로 제한합니다. 개인적으로 이러한 해결 방법을 사용하면 피할 수있는 많은 버그를 만들 수 있습니다. parseInt
안전한 구현을 선호하는 블랙리스트 는 더 나은 접근 방식이라고 생각합니다.
참고 URL : https://stackoverflow.com/questions/262427/why-does-parseint-yield-nan-with-arraymap
'Programing' 카테고리의 다른 글
Access-Control-Allow-Origin 와일드 카드 하위 도메인, 포트 및 프로토콜 (0) | 2020.03.23 |
---|---|
vim 줄 번호-기본적으로 어떻게 설정합니까? (0) | 2020.03.23 |
저장 프로 시저 란 무엇입니까? (0) | 2020.03.23 |
ASP.NET MVC에서보기 / 다운로드로 파일 반환 (0) | 2020.03.23 |
디렉토리에 대한 링크를 만드는 방법 (0) | 2020.03.23 |