map.(parseInt)方法详解
偶然间碰到这样一个问题:
["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:表示字符串
radix:表示其它进制转十进制的基数,范围在2~36,不在这个范围的返回NaN。该参数可以省略或为0,这种情况会根据字符串的开头来判断基数,而且字符串string中的数字不能大于radix才能正确返回数字结果值。
当参数 radix
的值为 0
,或没有设置该参数时,parseInt()
会根据 string
来判断数字的基数。具体规则如下:
-
如果
string
以"0x"
开头,parseInt()
会把string
的其余部分解析为十六进制的整数。 -
如果
string
以0
开头,版本低于ECMAScript 5的,基数为8。版本为ECMAScript 5的,基数为10。 -
如果
string
以 1 ~ 9 的数字开头,parseInt()
将把它解析为十进制的整数。
map 方法分析
语法:对数组的每个元素调用定义的回调函数并返回包含结果的数组。
array1.map(callbackfn[, thisArg])
map方法的第一个参数是一个回调函数,继续分析回调函数的语法
function callbackfn(value, index, array1)
回调函数接收的三个参数分别为:数组的值,值对应的索引,原数组。
为什么 ["1","2","3"].map(parseInt)
却返回 [1,NaN,NaN]
? 继续向下分析。。。
parseInt 需要两个参数 (val, radix) ,而它作为map的回调函数,map传递给了它三个参数
(value, index, array)。
如果想让 parseInt(string, radix)
返回 NaN,有两种情况:
-
第一个参数不能转换成数字。
-
第二个参数不在 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