在 JavaScript 开发中,我们经常会遇到一些“看起来不像数字”的数字,比如 NaN、Infinity、-Infinity,甚至 0/0。它们虽然属于 number 类型,但却代表了数学上的一些“异常”或“无意义”的结果。
今天我们就来深入剖析这些特殊的数字,搞清楚它们的来源、用途和常见陷阱!
🔍 一、什么是 NaN?
✅ 定义
NaN 是 Not-a-Number 的缩写,表示一个无效的数学计算结果。
但它有个神奇的地方:
typeof NaN === 'number' // true ✅
也就是说:NaN 虽然不是数字,但它的类型却是 number!
💡 这是 JavaScript 的设计特性之一,也是初学者最容易混淆的地方。
🌰 哪些情况会生成 NaN?
// 1. 非数字字符串转数字
parseInt('abc') // NaN
parseFloat('hello') // NaN
// 2. 无效的数学运算
Math.sqrt(-1) // NaN(负数开方)
'5' / 'abc' // NaN
undefined + 1 // NaN
null * 'hello' // NaN
// 3. 某些函数返回 NaN
Math.log(-1) // NaN
Math.pow(-1, 0.5) // NaN
⚠️ 二、如何检测 NaN?
⚠️ 注意:不能用 == 或 === 判断 NaN!
NaN === NaN // false ❌
NaN == NaN // false ❌
因为 NaN 不等于任何值,包括它自己。
✅ 正确方法:
方法 1:使用 isNaN()
isNaN(NaN) // true
isNaN('abc') // true
isNaN(123) // false
⚠️ 但注意:
isNaN()会先尝试将参数转换为数字,所以isNaN('abc')返回true,这可能会导致误判。
方法 2:使用 Number.isNaN()(推荐)
Number.isNaN(NaN) // true
Number.isNaN('abc') // false ✅(不会自动转换)
Number.isNaN(123) // false
✅ 更严格、更安全,只在传入的是真正的 NaN 时返回 true。
🔮 三、Infinity 与 -Infinity
✅ 含义
Infinity:正无穷大-Infinity:负无穷大
它们是当数值超出 JavaScript 数值范围时的结果。
🌰 产生方式:
1 / 0 // Infinity
-1 / 0 // -Infinity
Number.MAX_VALUE * 2 // Infinity
💡 JavaScript 使用 IEEE 754 双精度浮点数标准,最大可表示的数是
Number.MAX_VALUE(约 1.8e308),超过这个值就会变成Infinity。
🧩 特性
Infinity > 1000000000000000000 // true
-Infinity < -1 // true
Infinity + 1 === Infinity // true
Infinity - Infinity === NaN // true ✅(不确定)
⚠️
Infinity - Infinity结果是NaN,因为无法确定具体值。
🤯 四、0/0 为什么是 NaN?
这是数学中的一个经典问题:0 除以 0 是多少?
- 在数学中,这是一个“未定义”的表达式。
- 在 JavaScript 中,它被定义为
NaN。
0 / 0 // NaN
✅ 体现了 JavaScript 对“无效数学操作”的处理机制。
🎯 五、实际开发中的注意事项
1. 避免隐式类型转换引发的 NaN
let total = 0;
let prices = ['10', '20', 'abc'];
prices.forEach(price => {
total += price; // ❌ 会变成 NaN
});
console.log(total); // NaN
✅ 改进方案:
prices.forEach(price => {
const num = parseFloat(price);
if (!Number.isNaN(num)) {
total += num;
}
});
2. 数据验证时检查 NaN
function calculateAverage(numbers) {
let sum = 0;
let count = 0;
for (const num of numbers) {
if (Number.isNaN(num)) continue;
sum += num;
count++;
}
return count === 0 ? 0 : sum / count;
}
3. 使用 Number.isNaN() 替代全局 isNaN()
// ❌ 不推荐
if (isNaN(value)) { ... }
// ✅ 推荐
if (Number.isNaN(value)) { ... }
✅ 总结:特殊数字一览表
| 值 | 含义 | 是否为 number 类型 |
|---|---|---|
NaN | 无效的数学计算结果 | ✅ 是 |
Infinity | 正无穷大 | ✅ 是 |
-Infinity | 负无穷大 | ✅ 是 |
0/0 | 未定义的除法 | ✅ 是,结果为 NaN |
🔍 小贴士:
typeof NaN === 'number'是 JavaScript 的“设计缺陷”还是“设计哲学”?其实它是为了兼容 IEEE 754 标准而存在的。
🧠 记住一句话:
“
NaN是一个数字,但它不代表任何有效数值。”