偶然间碰到这样一个问题:



["1","2", "3"].map(parseInt)    //[ 1, NaN, NaN ]



运行结果 [ 1, NaN, NaN ] ,而不是[ 1, 2, 3 ]. 但是单独拿出来转换又可以。



console.log(parseInt(["1"]));  //1
console.log(parseInt(["2"]));  //2
console.log(parseInt(["3"]));  //3



下面我们从parseInt()方法和map()方法进行分析找出原因。

parseInt()方法分析

parseInt(s,radix)解析一个字符串,并返回一个整数。

  s:表示字符串

字符串string中的数字不能大于radix才能正确返回数字结果值。

当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string

  1. 如果 string 以 "0x" 开头,parseInt() 会把 string
  2. 如果 string 以 0
  3. 如果 string 以 1 ~ 9 的数字开头,parseInt()
map 方法分析

语法:对数组的每个元素调用定义的回调函数并返回包含结果的数组。



array1.map(callbackfn[, thisArg])



map方法的第一个参数是一个回调函数,继续分析回调函数的语法



function callbackfn(value, index, array1)



回调函数接收的三个参数分别为:数组的值,值对应的索引,原数组。

为什么 ["1","2","3"].map(parseInt) 却返回 [1,NaN,NaN]? 继续向下分析。。。(val, radix) ,而它作为map的回调函数,map传递给了它三个参数 (value, index, array)。如果想让 parseInt(string, radix)

  1. 第一个参数不能转换成数字。
  2. 第二个参数不在 2 到 36 之间。

我们传入的参数都能转换成数字,所以只能是第二种可能。



function parseInt(str, radix) {   
    return str+'-'+radix;   
};  
var a=["1", "2", "3"];  
console.log(a.map(parseInt)); //["1-0","2-1","3-2"]


map 函数将数组的值 value 传递给了 parseInt


a = ["1","2", "3"]
var parseInt = function(string, radix, obj) {
    return string + "-" + radix + "-" + obj;
};

console.log(a.map(parseInt)); //[ '1-0-1,2,3', '2-1-1,2,3', '3-2-1,2,3' ]


可以看出,map 确实为 parseInt 传递了三个参数 数组的值,值对应的索引,原数组。

可以看出,map的回调函数的参数index索引值作了parseInt的基数radix,索引index的起始值从0开始。

得出,正是由于map的回调函数的参数index索引值作了parseInt的基数radix,导致出现超范围的radix赋值和不合法的进制解析,才会返回NaN。



["1","2", "3"].map(parseInt)

[0]=parseInt("1",0);//十进制1

[1]=parseInt("2",1);//radix不在2~36的返回NaN

[2]=parseInt("3",2);//二进制数没有3,只有0 1 ,所以NaN