首先来看这样一个例子:
- [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
来源: http://www.jianshu.com/p/d4fbdbe7e43f