跳到主要内容

JavaScript 类型转换问题

typeof NaN

typeof NaN; // 'number'

NaN 是一个特殊的数值,它表示"不是一个数字"(Not-A-Number)。尽管 NaN 是一个特殊值,但它的类型仍然是 number。这可能会引起一些混淆,因为从字面上看,"不是一个数字"的类型却是 number

大整数精度问题

JavaScript 中最大的安全整数是 2^53 - 1,最小的安全整数是 -(2^53 - 1)。

9999999999999999; // 10000000000000000
10000000000000000; // 10000000000000000

当整数超过 53 位二进制位时,JavaScript 会出现精度问题。上面的例子中,第一个数字超过了最大安全整数,JavaScript 会将其四舍五入。这是因为 JavaScript 使用 IEEE 754 双精度浮点数表示所有数字,这导致了精度问题。

浮点数相加

0.1 + 0.2 === 0.3; // false
0.1 + 0.2; // 0.30000000000000004

同样由于 IEEE 754 标准的限制,JavaScript 中的浮点数运算也会出现精度问题。这是因为二进制浮点数表示法无法精确表示某些十进制小数。

Math 的一些特殊值

Math.max(); // -Infinity
Math.min(); // Infinity

Math.max() 如果没有参数,会返回 -Infinity,而 Math.min() 如果没有参数,会返回 Infinity

数组和对象的转换

[] + []; // ""
[] + {}; // "[object Object]"
{
}
+[]; // 0

当使用 + 运算符时:

  • 如果两个操作数都是数组,会将它们转换为字符串并拼接。
  • 如果一个操作数是数组,另一个是对象,会将它们都转换为字符串并拼接。
  • 如果一个操作数是对象,另一个是数组,会将对象转换为数字(通常为 0),然后与数组进行加法运算。

布尔值的转换

true + true + true === 3; // true
true - true === 0; // true
true == 1; // true
[] == 0; // true

在数学运算和比较运算中,true 会被转换为 1,false 会被转换为 0。空数组 [] 在比较运算中会被转换为 0。

字符串和数字的转换

(!+[] + [] + ![]).length; // 9
9 + '1'; // "91"
91 - '1'; // 90

在这些例子中:

  • !+[] 首先将 [] 转换为 0,然后取反得到 true,true 转换为 1。
  • [] 转换为 "",![] 转换为 false,然后转换为 ""。
  • 最后得到字符串 "9",访问其 length 属性得到 9。
  • 数字 9 与字符串 '1' 相加,会将数字转换为字符串,然后进行字符串拼接。
  • 数字 91 减去字符串 '1',会将字符串转换为数字,然后进行减法运算。

JavaScript 的类型转换规则有时会让人感到意外和困惑。理解这些特殊情况有助于我们写出更可靠的代码,避免潜在的错误。在比较值时要特别小心,必要时使用 === 进行严格相等比较而不是 ==