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