Javascript 为什么parseInt使用数组#map生成NaN?

Javascript 为什么parseInt使用数组#map生成NaN?,javascript,Javascript,从: 将产生: [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] 我敢打赌

从:

将产生:

[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]

我敢打赌,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 ) } );

Array.map
中的回调函数有三个参数:

与您链接到的相同:

回调由三个参数调用:元素的值、元素的索引和正在遍历的数组对象。”

因此,如果调用实际需要两个参数的函数
parseInt
,则第二个参数将是元素的索引

在本例中,您依次使用基数0、1和2调用了
parseInt
。第一个与不提供参数相同,因此它是基于输入的默认值(在本例中是以10为基数)。以1为基数是不可能的数字,以2为基数的3不是有效数字:

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导致它猜测八进制,这往往是有问题的。如果字符串以
0x
开头,它仍然会猜测十六进制)
map
正在传递第二个参数,它(在许多情况下)弄乱了
parseInt
的基数参数

如果使用下划线,则可以执行以下操作:

['10','1','100'].map(u.partial(parseInt,u,10))

或不带下划线:

['10','1','100'].map(函数(x){return parseInt(x,10);});

另一个(工作)快速修复:

var parseInt10 = function(x){return parseInt(x, 10);}

['0', '1', '2', '10', '15', '57'].map(parseInt10);
//[0, 1, 2, 10, 15, 57]

您可以使用箭头函数ES2015/ES6,只需将数字传递给parseInt。基数的默认值为10

[10, 20, 30].map(x => parseInt(x))
或者可以显式指定基数,以提高代码的可读性

[10, 20, 30].map(x => parseInt(x, 10))

在上面的示例中,基数显式设置为10

,您可以使用as iteratee函数解决此问题:

['1','2','3'].map(function(num) { return parseInt(num, 10); });
var a=['0','1','2','10','15','57'];

console.log(a);
parseInt
出于这个原因,应该避免使用IMHO。您可以将它包装起来,以便在以下情况下更安全:

const safe={
parseInt:(s,opt)=>{
常量{基数=10}=opt?opt:{};
返回parseInt(s,基数);
}
}
log(['1','2','3'].map(safe.parseInt));
console.log(
['1','10','11'].map(e=>safe.parseInt(e,{radix:2}))

);
parseInt仅在提供的字符串以0字符开头时采用八进制。哦,是的。它尝试根据输入“猜测”基数。对此很抱歉。对于lazy的:使用
.map(parseFloat)
,因为它只接受一个参数。或者使用
.map(Number)
。您可以使用arr.map(Math.floor)如果您想要不带手动滚动函数的整数。@Nikolai user669677非常好的建议!我建议您在Anwser中解释为什么parseInt正确解析第一个数字,并对第一个索引以外的数字出错