NaN 是 Not a Number 的缩写,它是 JavaScript 中一个特殊的数值(Number 类型),用于表示 “不是一个合法的数字”。
一、核心特性
-
类型是 Number
typeof NaN的结果是'number',这是一个非常重要且容易被忽略的特性。console.log(typeof NaN); // 'number' -
唯一不与自身相等的值
NaN是 JavaScript 中唯一一个不等于自身的值。这是它最奇特的性质。console.log(NaN === NaN); // false -
传播性任何与
NaN进行的数学运算,结果几乎都是NaN。console.log(NaN + 5); // NaN console.log(NaN * 10); // NaN console.log(Math.sqrt(NaN)); // NaN
二、产生 NaN 的常见场景
NaN 通常在以下几种情况下出现:
-
无效的数学运算
- 一个非数字字符串尝试被转换为数字失败时。
- 数字除以零(
0 / 0),注意:非零数字 / 0的结果是Infinity或-Infinity,而不是NaN。 - 负数的平方根。
const a = Number('hello'); // NaN const b = '123' - 'abc'; // NaN const c = 0 / 0; // NaN const d = Math.sqrt(-1); // NaN -
函数返回
- 许多数学函数在接收到无效参数时,会返回
NaN。
const e = Math.acos(2); // NaN (acos的参数范围是 -1 到 1) const f = parseInt('abc'); // NaN - 许多数学函数在接收到无效参数时,会返回
三、如何判断一个值是否为 NaN
由于 NaN === NaN 为 false,我们不能使用相等运算符来判断一个值是否为 NaN。正确的方法有两种:
-
使用全局函数
isNaN()isNaN()函数会尝试将传入的参数转换为数字。如果转换失败,它就返回true,否则返回false。- 注意:这是一个有缺陷的函数,因为它的转换逻辑可能导致一些非
NaN的值也返回true。
console.log(isNaN(NaN)); // true console.log(isNaN('hello')); // true (因为 'hello' 无法被转换为数字) console.log(isNaN('123')); // false (可以被转换为数字 123) console.log(isNaN(undefined)); // true (一个历史遗留问题) -
使用 ES6 新增的
Number.isNaN()Number.isNaN()是判断NaN的正确方法。它不会进行类型转换,只有当传入的值严格等于NaN时才返回true。
console.log(Number.isNaN(NaN)); // true console.log(Number.isNaN('hello')); // false (因为 'hello' 是字符串,不是 NaN) console.log(Number.isNaN(123)); // false console.log(Number.isNaN(undefined)); // false -
利用
NaN不等于自身的特性- 一个巧妙的技巧是检查一个值是否不等于它自己。
function isActuallyNaN(value) { return value !== value; } console.log(isActuallyNaN(NaN)); // true console.log(isActuallyNaN(123)); // false这个方法和
Number.isNaN()的效果完全相同。
四、总结与实践建议
- 理解
NaN的本质:它是一个表示 “计算失败” 或 “无效数字” 的特殊数值。 - 避免使用
isNaN():由于其怪异的类型转换行为,很容易引发 bug。 - 推荐使用
Number.isNaN():这是判断一个值是否为NaN的标准、可靠方法。 - 在计算前进行类型检查:为了从根源上避免
NaN,在进行数学运算前,最好先确保操作数是有效的数字。
function safeAdd(a, b) {
if (Number.isNaN(Number(a)) || Number.isNaN(Number(b))) {
throw new Error('传入的参数必须是有效的数字');
}
return Number(a) + Number(b);
}
console.log(safeAdd(5, '10')); // 15
console.log(safeAdd(5, 'hello')); // Error: 传入的参数必须是有效的数字