先来看一道经常会看到的前端面试题:
[1,2,3,4,5,6,7,8,9].map(parseInt)
输出的结果是什么?
很多第一次看到这道题或者是js基础不太牢靠的前端朋友可能会顺口就来,so easy,结果就是:[1,2,3,4,5,6,7,8,9]。
如果你直接这么提交答案,嘿嘿,老铁,等待你的就是一个零蛋哟!我们先来看看正确答案,然后再来分析是为什么。
正确答案:
[1, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]
那么,我们来看看,为什么输出的是这样一个“奇葩” 的答案吧。
首先,我们先来看一下parseInt方法的参数都有哪些:
parseInt(string, radix)
参数说明:
注:如果
parseInt
的字符不是指定基数中的数字,则忽略该字符和所有后续字符,并返回解析到该点的整数值。parseInt
将数字截断为整数值。允许使用前导空格和尾随空格。
string 必需。要被解析的字符串。 radix 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。
如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。
如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
从上面可以看出,parseInt的参数实际上是可以传两个的,第一个参数代表待转换的字符串,第二个参数则代表带解析的字符串的基数(也就是我们俗称的进制,如我们最常听说的:二进制(0101011)、十进制(1,2,3,4,5,6)、十六进制(如颜色值:#FFFFFF中的FFFFFF就是十六进制的表示形式))。
了解了parseInt的参数之后,我们再回过头来看看上面那道题是怎么计算出来的吧。
首先,数组[1,2,3,4,5,6,7,8,9]通过map方法进行循环,其实在循环体内部可以接收如下三个参数化:item、index、arr,即:
// 完整写法
[1,2,3,4,5,6,7,8,9].map((item,index,arr)=>{
});
然后,将parseInt放入到循环里面:
[1,2,3,4,5,6,7,8,9].map((item,index,arr)=>{
//parseInt(1,0);// 但第二个参数为0或者不传时,默认是十进制因此结果是:1
//parseInt(2,1);// 1进制数的合法数只有0,因此,2是非法的,因此结果是:NaN
//parseInt(3,2);// 2进制数的合法数只有0,1,因此,3是非法的,因此结果是:NaN
//parseInt(4,3);// ...
//parseInt(5,4);// ...
//parseInt(6,5);// ...
//parseInt(7,6);// ...
//parseInt(8,7);// ...
//parseInt(9,8);// ...
return parseInt(item,index);
});
从上面的代码我们就可以看出除了数组第一个元素因为索引是0默认代表10进制而输出1之外,其他的元素都因为所给数字超出了对应的基数范围而返回结果NaN。
好了,终于知道输出上面结果的原因了。老铁,是不是信心满满,觉得自己完全掌握了呢,来试一下这道题看看:
parseInt("1",3);//输出结果为:1
parseInt("3",3);//输出结果为:NaN
parseInt("12",3);//输出结果为:5
parseInt("14",3);//输出结果为:1
上面4个输出中,前两个很容易理解,刚刚都讲过了,不再赘述,我们重点来讲一下最后两个为什么输出这样一个结果:
// parseInt会将字符串"12"拆分成两个部分,分别是"1"和"2",因为"1"不在最后一位上,
// 因此,此处的"1"可不是代表数字1,而是代表有一个基数,基数是什么呢?
// 就是我们传的第二个参数3,也就是说,这里的"1"我们可以等价为3,
// 后面的"2",因为是最后一位,只要他是在合法范围内的数字,那么他是多少就是多少,也就是说"2"=2;
// 然后,我们在讲两个数字相加:3+2=5;所以最后输出的结果便是5啦
parseInt("12",3);//输出结果为:5
// 同理,可将"14"拆分成"1"和"4",这里有一个比较特殊的地方,因为"4"是不合法的数字,
// 因为以3为基数的只能由0,1,2者三个数字组成,在parseInt中,如果遇到不合法的数字,
// 会被直接忽略,只看那些合法的数字。那么,把"4"忽略掉之后,就只剩下一个"1"了,
// 因为"1"是最后一位,所以数字是多少就是多少,因此,最终输出结果为:1
parseInt("14",3);// 输出结果为:1
以上便是本人对parseInt的一些粗浅的看法与理解,记录下来一是为了备忘,二也是为了给以后踩坑的小伙伴们一些参考。