原文链接 ​​Solving a Mystery Behavior of parseInt() in JavaScript​​ -- 作者 ​​Dmitri Pavlutin​​

​parseInt()​​​ 是一个内置的 ​​JavaScript​​​ 函数,它可以将数字字符串解析为整数。比如,我们将数字字符串 ​​'100'​​ 解析为整数:

const number = parseInt('100');
number; // 100

如预期那样,​​'100'​​​ 被解析为整数 ​​100​​。

​parseInt(numericalString, radix)​​​ 也接受第二个参数:​​radix​​​(基数),另一个参数是数字字符串 ​​numericalString​​​。​​radix​​​ 参数允许你解析来自不同数字基数的字符串为整数,基数通常有 ​​2,8, 10 和 16​​。

我们使用基数为 ​​2​​​ 的 ​​parseInt()​​ 来解析一个数字字符串:

const number = parseInt('100', 2);
number; // 4

​parseInt('100', 2)​​​ 以基数 ​​2​​​ 解析 ​​'100'​​​ 为一个整数:所以它返回十进制数值 ​​4​​。

上面就是对 ​​parseInt()​​ 方法的简单介绍。

1. parseInt() 中的一个怪异行为

​parseInt(numericalString)​​ 总是将其第一个参数转换成字符串(如果它不是字符串的话),然后将这个字符串数字解析成整数。

这就是为什么你可以(但是不应这么做! )使用 ​​parseInt()​​ 来提取浮点数的整数部分:

parseInt(0.5); // => 0
parseInt(0.05); // => 0
parseInt(0.005); // => 0
parseInt(0.0005); // => 0
parseInt(0.00005); // => 0
parseInt(0.000005); // => 0

取出浮点数,比如 ​​0.5​​​,​​0.05​​​ 等等整数的部分。结果就是 ​​0​​。这跟我们的预期结果一样。

那么提取 ​​0.0000005​​ 整数的部分会怎样呢?

parseInt(0.0000005); // => 5

​parseInt()​​​ 将浮点数 ​​0.0000005​​​ 解析为 ​​5​​。这就很有趣且不符合预期...

为什么 ​​parseInt(0.0000005)​​ 会有如此怪异的行为呢?

2.解决 parseInt() 该怪异行为

我们回顾下,​​parseInt(numericalString)​​ 对它的第一个参数做了什么:如果不是字符串,就将其转换为一个字符串,然后解析,之后返回解析的整数。

这可能是第一个线索。

我们手动将浮点数转换为字符串表现形式:

String(0.5); // => '0.5'
String(0.05); // => '0.05'
String(0.005); // => '0.005'
String(0.0005); // => '0.0005'
String(0.00005); // => '0.00005'
String(0.000005); // => '0.000005'
String(0.0000005); // => '5e-7'

​String(0.0000005)​​ 数值的显式转换和其它浮点数不同:它是指数符号​​exponential notation​​ 字符串表现形式。

这是第二个线索 -- 很重要!

然后当指数符号字符串解析为整数,你就会得到整数 ​​5​​:

parseInt(0.0000005); // => 5
// same as
parseInt(5e-7); // => 5
// same as
parseInt('5e-7'); // => 5

​parseInt('5e-7')​​​ 考虑第一个数字 ​​'5'​​​,跳过了 ​​'e-7'​​。

解密了!因为 ​​parseInt()​​​ 总是将它第一个参数转换为字符串,浮点数字小于 解决 JavaScript 中 parseInt() 的一个怪异行为_字符串 就会被写成指数符号的形式。​​​parseInt()​​ 从浮点数的指数符号中取出整数。

译者加 -- 注意,​​parseInt()​​​ 取字符串前面整数的部分,比如:​​parseInt('12Jimmy34')​​​ 则有返回结果 ​​12​

备注,安全地取出浮点数整数的部分,我推荐使用 ​​Math.floor()​​ 函数:

Math.floor(0.5); // => 0
Math.floor(0.05); // => 0
Math.floor(0.005); // => 0
Math.floor(0.0005); // => 0
Math.floor(0.00005); // => 0
Math.floor(0.000005); // => 0
Math.floor(0.0000005); // => 0

3. 总结

​parseInt()​​ 是个将数字字符串转换为整数的函数。

当你使用 ​​parseInt()​​ 获取浮点数的整数部分的时候,要小心。

小于 解决 JavaScript 中 parseInt() 的一个怪异行为_字符串 的浮点数(比如 ​​​0.0000005​​​ 等同于 解决 JavaScript 中 parseInt() 的一个怪异行为_前端_03)被转换为以指数符号表示形式(比如 ​​​5e-7​​​ 是 ​​0.0000005​​​ 指数符号形式)。这就是为什么使用 ​​parseInt()​​​ 作用于如此小的浮点数会出现非预期效果:仅解析指数表示形式的重要部分(比如 ​​5e-7​​​ 中的 ​​5​​)。

挑战:你可以解释为什么 parseInt(999999999999999999999) 会等于 ​1​ 可以在下面评论区写出你的思路。