面试题 | parseInt()面试题,99%的人会做错!

摘要:本文详细解析了一道JavaScript面试题,涉及map函数和parseInt函数的用法。当parseInt作为map的迭代函数时,由于缺少第二个参数(进制),导致结果并非预期的[1,2,3],而是[1,NaN,NaN]。文章还通过多个例子解释了parseInt的进制解析规则,并提供了额外的变种题供读者思考。

面试题:请你说出以下代码的执行结果

['1', '2', '3'].map(parseInt);

如果大家第一次做这道题,几乎都会认为答案是 [1,2,3], 原因很简单:paseInt 会把一个字符串转化为整数。 ‘1’, ‘2’, ‘3’ 转化为整数分别是 1 , 2 , 3,所以,以上代码会循环执行 3 次,分别返回 1 , 2 , 3。

视频参考:前端面试官:parseInt( )执行结果是多少?_哔哩哔哩

知识回顾


map() 函数

在大多数场景下,我们使用 map 函数只会使用到它的第一个参数,也就是当前遍历的元素。比如以下代码,第一次 item 是 '1' ,第二次 item 是 '2'…

我们忽略了 map 函数的第二个参数和第三个参数。map 函数的第二个参数是当前遍历元素的下标(或者说索引)。map 函数的第三个参数是数组本身。

const result = ["1", "2", "3"].map((item, index, arr) => {
    console.log(arr); // ['1', '2', '3']
    console.log(index); // 当前索引
    console.log(item); // 当前遍历的元素
    return item * 2;
});

parseInt() 函数

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

语法格式:parseInt(string, radix)

parseInt接收两个参数:

  • 第一个参数string:要被解析的字符串,如果不是字符串会被转换,忽视空格符
  • 第二个参数radix:要解析的数字的基数。该值介于2 ~ 36之间。默认值为10,表示十进制。这个参数表示将前面的字符从radix进制转化为十进制,即,radix 用于描述你当前传入的字符串是 几进制。

1、在没有指定基数,或者基数为0的情况下,parseInt()会根据string参数来判断数字的基数。

也就是说,如果你没有传第二个参数 radix或者 radix为0的情况下,那么根据以下规则来自动判断 string 是几进制:

① 如果字符串string以"0x"或者"0X"开头, 则基数是16 (16进制);

② 如果字符串string以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决定。

ECMAScript 5 规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出radix参数的值。

③ 如果字符串string以其它任何值开头,则基数是10 (十进制);

④ 如果你传第二个参数 radix,radix的范围需要在2 ~ 36之内。如果在2 ~ 36之外会返回NaN。

2、如果radix2 ~ 36之外会返回NaN。

我们看以下几个例子:

示例1

console.log(parseInt(5, 8)); 

结果:5

解释:将字符串"5"解析为十进制数,因为第二个参数为8,表示使用八进制解析。但是"5"并不是八进制数字,所以解析结果为十进制数5。

示例2

console.log(parseInt(5, 2));  

结果为:NaN

解释:将字符串"5"解析为二进制数,因为第二个参数为2,表示使用二进制解析。但是"5"并不是有效的二进制数字,所以解析结果为NaN(Not a Number)。

示例3

console.log(parseInt(5, 0)); 

结果为:5

解释:第二个参数为0时,parseInt函数会根据字符串的前缀来判断要使用的进制。由于"5"没有前缀,所以默认按照十进制解析,结果为十进制数5。

示例4

console.log(parseInt(5, 1)); 

结果为:NaN

解释:第二个参数为1,表示使用基数为1进行解析。在数学中,基数必须大于1,因此,无法解析为有效的数字,结果为NaN。

示例5

console.log(parseInt(123, 5)); 

结果为:38

解释:将字符串"123"解析为五进制数,因为第二个参数为5,表示使用五进制解析。将字符串中的每个字符按照五进制转换为数字,得到1*5^2 + 2*5^1 + 3*5^0 = 38。因此,解析结果为38。

题目分析

理解了 map 和 parseInt 之后,我们再来看 ['1', '2', '3'].map(parseInt); 

其实 ['1', '2', '3'].map(parseInt)  等同于 parseInt(item, index, array));

因为parseInt只接收2个参数,因此,map的callback函数只把(item:元素值, index:索引)这两个有效参数传给了parseInt,第三个参数无效。

那么这个原题就可以分解为求解下面这三个函数的值,并返回结果

第一次循环:

parseInt('1', 0);  // 参数:'1',进制值为默认的十进制(0)
// 返回结果:1

第二次循环:

parseInt('2', 1); // 参数:'2',进制值为 1
// 返回结果:NaN(因为2是无效的一进制数字)

第三次循环:

parseInt('3', 2); // 参数:'3',进制值为 2
// 返回结果:NaN(因为3是无效的二进制数字)

因此,返回的结果是:[1, NaN, NaN]

哎,所以为了避免这个坑,平时写 map 还是不要偷懒了,完整的写法才更直观且更容易维护。

['1', '2', '3'].map(value => parseInt(value));

面试题的变种

console.log(parseInt(1/0, 19))  // 18

解析:parseInt里面有两个参数,第二个参数是19,十九进制包括(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i);然后分析第一个参数1/0,它的运算结果是 Infinity,那么相当于要把 Infinity 从19进制转化为十进制,我们从第一个字符I开始 – 19进制有i,表示18,接下来字母n ,-- 哦豁,19进制里面没有 n,既然不认识,那就不管了,立即返回i(对应十进制中的18),所以返回结果为:18。 

console.log(parseInt(false, 16)) // 250

解析:parseInt里面有两个参数,第二个参数16,十六进制包括(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f);然后分析第一个参数false,转化为字符串(parseInt第一个参数非字符串先转化为字符串)==> false。,从第一个字符开始分析,f ,a,接下来是 l,16进制里面没有 l。立即返回fa (十六进制的fa转换成十进制等于250),结果为:250

console.log(parseInt(parseInt, 16)) // 15

解析:parseInt里面有两个参数,第二个参数是16,十六进制包括(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f);然后分析第一个参数 parseInt,转化为字符串,我们看看String(parseInt)结果是什么, function parseInt() { [native code] }, 好的,从第一个字符开始分析,f认识,u不认识,立即返回f (十六进制的f转换成十进制等于15), 返回结果:15

console.log(parseInt({}, 16)) // NaN

解析:parseInt里面有两个参数,第二个参数是16,十六进制包括(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f);然后分析第一个参数{}, 我们看看String({})是个啥,[object Object], 第一个字符是[, 不认识,那就返回 NaN 吧。

最后来总结一下:

① map函数需要注意回调函数的三个参数涵义,编写代码时尽量写完整,防止掉坑。

② parseInt第一个参数如果不是字符串,先尝试转换为字符串,再进行进制转化。

③ parseInt第二个参数根据上面的转化规则进行分析即可

④ parseInt第二个参数范围到36,其实是0~9的十进制,加上26个字母,即三十六进制

相信只要掌握了parseInt的转化规则,按照套路来拆解分析,下次再遇到类似的奇葩问题,也能手到擒来。

参考资料:parseInt()函数绝不是你想的那么简单 | 前端面试官:parseInt( )执行结果是多少?_哔哩哔哩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值