前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >透过网红面试题,超详细解析 parseInt,学不懂找我

透过网红面试题,超详细解析 parseInt,学不懂找我

作者头像
coder_koala
发布2021-09-18 16:48:53
3.4K0
发布2021-09-18 16:48:53
举报

最近面试了几个前端开发,我都问了一道算是网红面试题,其中两个应届毕业生,两个两年开发经验的,他们都没有给到我想要的答案。

很多人可能觉得这种网红题目是在刁难人,没有实际的意义。但是在面试时,有时候想要快速了解一个人对某些知识的掌握,还是有意义的。而且说出答案是一回事,重点还在于他们得出答案的分析过程。

考察的点

代码语言:javascript
复制
console.log([1, 2, 3, 4].map(parseInt))

这道题考察的点:

  1. 对数组map方法的掌握
  2. parseInt函数的了解
  3. 考察对进制转化的掌握
  4. parseInt与parseFloat有何区别

废话不多说,直接上主菜~

代码语言:javascript
复制
console.log([1, 2, 3, 4].map(parseInt))
  • 输出结果:1,NaN, NaN, NaN

这个答案,很多人都是清楚的,接下来我的问题是,可以说一下map迭代的过程吗?

数组map方法

数组的map方法,是ES5中为数组定义的迭代方法,返回结果是一个新数组,其结果是该数组中的每一个元素调用一次提供的函数后的返回值:

语法:

代码语言:javascript
复制
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
 // 新数组的返回元素
}[, thisArg])

参数:

  • callback:数组迭代的每一项执行的回调函数,可以有三个参数:
    • currentValue:当前迭代项
    • index:当前迭代项的索引 (可选)
    • array: map 方法调用的数组(可选)
  • thisObject:在执行回调函数时定义的 this 对象(没有传递或者为 null,将会使用全局对象)。

我们简单温故了数组map方法, 接下来再详细的认识一下parseInt方法。

parseInt方法

不少人会觉得parseInt不就是将字符串转成一个整数吗, 平时经常使用。但是关于parseInt还真要仔细的说道说道,因为这里有些细节非常容易忽视。

语法

代码语言:javascript
复制
parseInt(string, radix);

返回值

从给定的字符串中解析出一个整数,或者NaN

关于返回NaN:

  • radix 小于 2 或大于 36
  • 第一个非空格字符不能转换为数字。

parseInt(string, radix) 解析一个字符串并返回指定基数的十进制整数, radix 是2-36之间的整数,表示被解析字符串的基数。

这是MDN给的解释,其实理解起来有点困难,这里我一步步的拆解一下。首先,解析一个字符串并返回指定基数的十进制整数这句话怎么理解呢?

parseInt 第一个参数理解

第一个参数是字符串?其实并不是...

是指将parseInt第一个参数字符串转为整数, 那如果传入的第一个参数不是字符串,如何处理呢, 这里就有一个转化规则(其实也是parseInt的一个小坑):

parseInt转化规则

  1. 如果第一个参数传入的不是字符串,首先会默认将传入的参数转为字符串(使用toString
  2. 从左边开始查找有效数字字符,转为数字;当遇到非有效数字字符,则停止查找

举几个例子:

代码语言:javascript
复制
parseInt(12); // 12
parseInt('20px') // 20
parseInt("p20")  //NaN

通过上面的代码,结合转化规则来看:

parseInt(12),首先是将数值12转为字符串'12', 然后再转为整数。

parseInt('20px'),从左边开始查找,当找到字符p时,发现是非有效字符,停止查找,对已找到的有效数字进行转换,所以结果是将字符串'20'转为整数。

parseInt("p20") ,当第一个字符不能转为数字,parseInt会返回NaN

parseInt 第二个参数理解

回到我们上边分析MDN的原话:解析一个字符串并返回指定基数的十进制整数, 这个还要注意指定基数, 就是parseInt(string,radix)的第二个参数「radix」,就是这个基数, 表示将第一个参数string当作radix进制。

这里有一个注意点,我发现有的人容易弄混:

parseInt是将radix进制的字符串转为十进制的整数(很多人弄混成:转成radix进制的整数)。 也就是说parseInt返回的的结果只能是十进制的整数或者NaN

那我们之前没有传第二个参数啊,是什么情况呢???

规则

  • radix如果为undefined、0或者未指定的:
    • 一般情况下,radix为10(十进制)
    • 如果string传入的是以0x(一个0,后面是小写或大写的X)开头, 那么radix就会被当作传入的为16, string就被的看作16进制去解析
  • radix是在2-36之间的整数,表示2-36进制; 如果不在2-36之间,最后返回结果都是NaN

同样举几个例子,结合规则看一下:

代码语言:javascript
复制
parseInt('0x11') // 17
parseInt('10', 2)  // 1
parseInt('12', 2)  // 1

我们简单分析一下上面的代码:parseInt('0x11')省略了radix参数,并且以0x开头,那么就将0x11看作16进制来解析,11转为十进制整数,结果为17(如果对进制转换不熟悉,后面有详细讲解)。

parseInt(10, 2), radix传入2,将'10'看作2进制,转换成十进制整数就是1。

parseInt('12', 2), 这个转换结果也为1, 这里又有一个坑需要注意,当解析到字符串'2'时,发现是非有效数字,(有的人可能会说:2怎么不是有效数字了!!),咳,这里要注意,我们是将'12'看作二进制的,二进制只有01,所以2当然不是有效数字, 将字符串'2'忽略,转换结果就是1。

通过上面的几个例子相信对parseInt有一定的了解,这里我要补充一点关于进制转换的知识,就当复习巩固了(因为面试时,我变更了一下题目的数值,发现有的人不会,或者说忘记了进制转换)

任意进制如何转十进制

二进制、八进制、十六进制等向十进制转换都是很容易的,就是按位相加,位指的是位权重(位上的数字乘以权重),权重就是N进制的第几位的位数见一次方。假如当前数字是N进制,那么:

  • 对于整数部分,从右往左看, 第i位的位权重为:
N ^ {i-1}
  • 对于小数部分,需要从左向右看,第m位的位权重为:
N^{-m}

举几个例子看一下:

分别将下面的数字按要求转为十进制

代码语言:javascript
复制
FA1089  // 将16进制转为十进制
673.321 // 将8进制转为十进制
011001  // 将2进制转为十进制

FA1089 =

15*16^5

+

10*16^4

+

1*16^3

+

0 * 16^2

+

8 * 16^1

+

9 * 16^0

我将每一位的转换做了连线,方便理解,FA1089一共6位, 从右往左看,第一位9,位权重为:

9 * 16^{1-1}

,依次类推...需要注意的是: A~F对应的是十六进制的10-15

接下来看看一下八进制673.321的转换:

673.321 =

6 * 8^2

+

7 * 8^1

+

3*8^0

+

3 *8^{-1}

+

2 * 8^{-2}

+

1 * 8^{-3}

image.png

二进制转十进制转换方式也是同理,这里就不赘述。

解题

前面对于数据遍历方法mapparseInt方法以及进制转换,铺垫了这么多, 接下来就来分析一下正题:

代码语言:javascript
复制
[1, 2, 3, 4].map(parseInt)

map迭代过程如下:

  1. parseInt(1, 0), 前面讲到 parseInt第二个参数不传、传的是0或者undefined,默认当做十进制处理, 输出结果为:1 ;
  2. parseInt(2, 1), 第二个参数为1, 不在2-36之间, 返回结果NaN;
  3. parseInt(3, 2), 将3作为二进制转换为十进制整数,但是二进制只有0和1,找二进制数字就什么都没有找到, 所以输出NaN ;
  4. parseInt(4, 3), 这里也是,4 不是3进制中数字, 输出结果NaN

这道题的答案就出来了: 1 NaN NaN NaN

拓展

parseInt还有一个兄弟方法parseFloat, 你知道他们的异同点吗,以及它们和Number有什么区别?

首先都知道parseIntparseFloat和Number都是将一个变量转换为数字类型。

parseInt 和 parseFloat 的区别:

  • parseFloat只能用于将字符串转换成10进制的浮点数,只接受一个参数,不能识别数据的原始进制,所有数据基数按10进制转换。
  • parseInt 将字符串转为10进制 整数,并且还支持第二个参数指定第一个参数的原始进制。

Number与parseInt的区别:

parseInt 处理机制:

  • parseInt如果处理的值是字符串,从字符串左侧开始查找,遇到非有效数字则停止查找(+-号除外);
  • 如果不是字符串,则先转为字符串,然后开始查找有效数字

注意:上边提到的有效数字,并不是数字都是有效数字, 而应该根据parseInt第二个参数指定的进制来看。比如指定的二进制, 那么2、3这样的数字就是非有效数字

Number处理机制:

  1. 如果是Boolean值,true和false将分别转换为1和0。
  2. 如果是数字值,只是简单的传入和返回。
  3. 如果是null值,返回 0。
  4. 如果是undefined,返回NaN。
  5. 如果是字符串,遵循下列规则:
    • 如果是字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即“1”变成1,“123”会变成123,而“011”会变成11(前导的零被忽略了);
    • 如果字符串中包含有效的浮点格式,如“1.1”,则将其转换为对应的浮点数值(同样也会忽略前导零);
    • 如果字符串中包含有效的十六进制格式,例如"0xf",则将其他转换为相同大小的十进制整数值;
    • 如果字符串是空的(不包含任何字符),则将其转换为0;
    • 如果字符串中包含除上述格式之外的字符,则将其他转换成NaN.
  6. 如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用的对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。

温故知新

通过上面的学习, 通过一道练习题目,温习一下文章讲解的内容:

代码语言:javascript
复制
var arr = [10, 18, 0, 10, 42, 23]
arr = arr.map(parseInt)
console.log(arr) 
如果觉得这篇文章还不错
点击下面卡片关注我


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员成长指北 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 考察的点
  • 数组map方法
  • parseInt方法
    • parseInt 第一个参数理解
      • parseInt 第二个参数理解
        • 任意进制如何转十进制
          • 解题
            • 拓展
            • 温故知新
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档