Appearance
05. 我真不会 parseInt
场景1
一个简单的需求,要求对一个浮点数进行取整操作,你可能会立马想到以下代码:
js
parseInt(x) // x 为浮点数,例如 1.2
1
这个对于大部分情况是没问题的:
js
parseInt(0.3) // 0
parseInt(0.03) // 0
parseInt(0.003) // 0
parseInt(0.0003) // 0
parseInt(0.00003) // 0
parseInt(0.000003) // 0
1
2
3
4
5
6
2
3
4
5
6
继续执行 parseInt(0.0000003)
,这个返回的结果居然是 3
?
这是因为 parseInt
执行的原理: 如果 parseInt
接受的第一个参数不是一个字符串,则将其转换为字符串 (使用 ToString 转换)。 需要注意:
- 返回值是从给定的字符串中解析出的一个整数,例如
'123a'
返回123
。 - 字符串开头的空白符将会被忽略,例如
123
返回123
。
所以 parseInt(0.0000003)
的具体转换过程为:
js
x = 0.0000003
x = 3e-7
x = x.toString() // '3e-7'
x = parseInt('3e-7')
x = 3
1
2
3
4
5
2
3
4
5
基于以上分析,MDN 也给出了警告:因此当对非常大或非常小的数字使用数字时,使用 parseInt
截断数字将产生意外结果。parseInt
不应替代 Math.floor()
。
场景2
对数组中所有的浮点数取整,例如 [1.1, 2.3, 3.5]
应该返回 [1, 2, 3]
。
如果你写出了以下代码,运行后,结果是不对的。
js
let res = [1.1, 2.3, 3.5].map(parseInt)
1
上述代码结果为 [1, NaN, NaN]
。
parseInt
其实接收两个参数,第一个参数为一个待解析的字符串,第二个参数表示该字符串 基数。对于 parseInt(str, radix)
,str
是一个基于 radix
进制的数字字符串,返回一个该数的十进制形式。例如 parseInt('111', 2)
返回 7
。
分析 [1.1, 2.3, 3.5].map(parseInt)
,parseInt
能够接收两个参数,而 map
能够提供两个参数:map(value, index)
,因此数组中的 v, k
就变成参数传递给了 parseInt
。
[1.1, 2.3, 3.5].map(parseInt)
的过程如下所示:
js
x = [1.1, 2.3, 3.5]
x[0] = parseInt(1.1, 0) // 第二个参数为 0,表示十进制,返回 1
x[1] = parseInt(2.3, 1) // 不存在 1 进制,出错,处理为 NaN
x[2] = parseInt(3.5, 2) // 一个 2 进制的 3,出错,处理为 NaN
x -> [1, NaN, NaN]
1
2
3
4
5
2
3
4
5
更多细节,请阅读 MDN 文档:MDN parseInt