Appearance
好问题 👍 这几个其实是一组常见的“数值安全判断函数”,很多人混用。 下面我给出 一张完整对比表 + 推荐用法总结,一眼就能看明白。
🔍 一、总体区别概览
| 表达式 | 是否类型转换 | 判断逻辑 | 返回 true 条件 | 常见坑 |
|---|---|---|---|---|
isNaN(x) | ✅ 会转换 | Number(x) 是 NaN | 'foo', 'NaN', undefined 都 true | 太宽松,容易误判 |
Number.isNaN(x) | ❌ 不转换 | x === NaN | 仅 NaN 自身 | 安全、推荐 |
isFinite(x) | ✅ 会转换 | Number(x) 是有限数 | 数字字符串也 true,如 '3' | 太宽松 |
Number.isFinite(x) | ❌ 不转换 | typeof x === 'number' && x 是有限数 | 仅真数值类型且有限 | 安全、推荐 |
typeof x === 'number' | ❌ 不转换 | 类型检查 | 包含 NaN, Infinity | 只看类型,不看值 |
📘 二、核心对比示例
js
isNaN("foo"); // ✅ true ❌ 错误判断
Number.isNaN("foo"); // ❌ false ✅ 正确
isFinite("123"); // ✅ true ❌ 错误判断(字符串也算)
Number.isFinite("123"); // ❌ false ✅ 正确
typeof NaN === "number"; // ✅ true (NaN 仍是 number)
typeof Infinity === "number"; // ✅ true (Infinity 也是 number)
Number.isFinite(NaN); // ❌ false (NaN 非有限数)
Number.isFinite(Infinity); // ❌ false (无穷大)✅ 三、推荐实战组合
| 目的 | 推荐写法 | 说明 |
|---|---|---|
| 判断一个值是否是数字类型(含 NaN、∞) | typeof x === 'number' | 只看类型 |
| 判断一个值是否是有限数字 | Number.isFinite(x) | ✅ 这是**判断“有效数值”**的标准写法 |
| 判断一个值是否为 NaN 本身 | Number.isNaN(x) | ✅ 不会误判字符串 |
| 判断字符串能否安全转数字 | !Number.isNaN(Number(x)) | 常用于输入框解析 |
⚠️ 四、常见误区
isNaN('') === false因为空字符串会被强转成0→ 不是 NaN。isFinite(null) === true因为Number(null)是0。这就是为什么Number.isFinite更可靠。typeof NaN === 'number'这不是 bug,NaN是 “Not-a-Number” 的“数值类型表示”,所以它仍是number类型。
💡 五、实用封装示例
若你要判断“是否是真正的可用数值”,建议写成:
ts
function isValidNumber(x: unknown): x is number {
return typeof x === "number" && Number.isFinite(x);
}- ✅ 排除
NaN - ✅ 排除
Infinity - ✅ 不接受字符串或其它类型
示例:
js
isValidNumber(123); // true
isValidNumber("123"); // false
isValidNumber(NaN); // false
isValidNumber(Infinity); // false✅ 小结(记忆口诀)
🔸
Number.isNaN()/Number.isFinite()—— 不转换,更安全; 🔸 全局的isNaN()/isFinite()—— 会强转字符串,容易误判; 🔸typeof x === 'number'—— 只看类型,不代表值有效。