Skip to content
On this page

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

继续执行 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

基于以上分析,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

更多细节,请阅读 MDN 文档:MDN parseInt