首先来看这样一个例子:
[1, 7, 14].map(item => parseInt(item))
// 返回的结果是这样的 [1, 7, 14]
// 上面的结果还是正常的,但是把上面这段代码改写一下
[1, 7, 14].map(parseInt)
// 返回的结果是这样的 [1, NaN, 1]
// 为什么会这样?
造成上面这种现象的原因有两个:
- map函数的入参函数接受三个参数,分别是数组遍历到的值,该值的索引以及数组本身
- parseInt函数的使用方法
首先来看map函数,我们把parseInt函数改成console.log来打印一下看看
[1, 7, 14].map(console.log)
// 1 0 [1, 7, 14]
// 7 1 [1, 7, 14]
// 14 2 [1, 7, 14]
// 可以发现入参其实有三个
回过头来看看原来的例子其实就相当于
[1, 7, 14].map(parseInt)
// 上面的这段代码其实就相当于下面这段代码
[1, 7, 14].map((item, inndex, arr) => parseInt(item, index, arr))
接下来的问题就是parseInt的锅了,关于parseInt我们需要了解以下这些内容
- parseInt接受两个入参,所以上面的arr入参其实就直接被忽略了,parseInt的第一个参数是需要被转化的值,第二个参数是radix(进制),radix的取值为2-36,如果不传相当于默认是十进制。最后转化的结果是转化为十进制。
在radix为 undefined,或者基数为 0 或者没有指定的情况下,JavaScript 作如下处理:
如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制).
如果字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决定。ECMAScript 5 规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出radix参数的值。
如果字符串 string 以其它任何值开头,则基数是10 (十进制)。
-
parseInt的第一个参数可以是字符串或者数字,如果传入其他的东西直接返回NaN,如果是字符串则先转化为数字,转化的原则是从第一个字符开始转化,直到最后一个不能转化的字符,如'12.3aaa'会被转化为12.3,然后把数字进行进制的转化
-
在进制转化的过程中,如果出现该进制中不存在的数字或是碰到小数点时就停止转化,返回已转化的结果,如果第一个数字就不能转化就返回NaN
知道了上面的这些规则,我们就可以解释之前的奇怪现象了
[1, 7, 14].map(parseInt)
// 进行到第0项时,radix为0,进行特殊处理,处理为十进制,所以第一个返回的是1
// 进行到第1项时,radix为1,7不是这个进制里面的数字,返回NaN
// 进行到第2项时,radix为2,14的第一个数字是2进制里面的数字,但是4不是,所以进行的操作是parseInt(1, 2),所以结果是1
补充
parseInt和Number.parseInt的区别:
parseInt('123aaaa') // 12
Number.parseInt('123aaaa') // NaN
网友评论