写 JavaScript 的时候我们经常会遇到要判断一个值是不是“有限的数”或者是不是“不是一个数NaN”。早期的 ES5 提供了两个全局函数isFinite()和isNaN()后来到了 ES6又在Number对象上加了两个新方法Number.isFinite()和Number.isNaN()。看起来它们干的是差不多的事但其实用起来差别挺大。这篇文章就用简单的话和例子把它们的不同讲明白帮你少踩坑。一、isFinite()和Number.isFinite()有什么不同1. 全局的isFinite()是怎么工作的它是干啥的用来检查你给它的值最后能不能变成一个正常的、不是无穷大的数字。它会偷偷做一件事先把你的值用Number()转一下不管原来是什么类型都先试着变成数字然后再看这个数字是不是有限的。比如console.log(isFinite(123)); // true本来就是数字 console.log(isFinite(123)); // true字符串 123 被转成了数字 123 console.log(isFinite(abc)); // falseabc 转出来是 NaN console.log(isFinite(true)); // truetrue 被当成 1 console.log(isFinite(null)); // truenull 被当成 02.Number.isFinite()更老实它是干啥的只看你传进来的东西是不是一个真正的数字并且这个数字不能是无穷大或者 NaN。它不会乱动你的数据如果你传的是字符串、布尔值或者其他类型它直接说“不行”根本不去尝试转换。比如console.log(Number.isFinite(123)); // true是数字也没问题 console.log(Number.isFinite(123)); // false虽然是数字样子的字符串但它不是数字类型 console.log(Number.isFinite(NaN)); // false console.log(Number.isFinite(Infinity)); // false console.log(Number.isFinite(true)); // false布尔值不算数字✅简单说Number.isFinite()更靠谱因为它不乱改你的数据只认真正的数字。二、isNaN()和Number.isNaN()差在哪1. 全局的isNaN()容易让人误会它表面上是查 NaN实际上不是它先把你给的值转成数字如果转完是 NaN就返回 true。所以它其实是在问“这东西能变成正常数字吗”而不是“它是不是 NaN”举个例子console.log(isNaN(NaN)); // true确实是 NaN console.log(isNaN(abc)); // true因为 abc 转数字失败变成 NaN console.log(isNaN(123)); // false123 能转成 123没问题 console.log(isNaN(undefined)); // trueundefined 转数字是 NaN console.log(isNaN({})); // true对象转数字也是 NaN console.log(isNaN(true)); // falsetrue 转成 1不是 NaN⚠️ 问题来了isNaN(hello)返回 true但hello根本不是NaN它只是一个字符串这种设计很容易让人搞错逻辑。2.Number.isNaN()才是真的查 NaN它只做一件事看看你给的值是不是严格等于NaN。它很死板如果不是数字类型直接返回 false只有当值本身就是NaN时才返回 true。比如console.log(Number.isNaN(NaN)); // true真的是 NaN console.log(Number.isNaN(NaN)); // false这是字符串不是 NaN console.log(Number.isNaN(undefined)); // false不是数字 console.log(Number.isNaN(123)); // false是正常数字 console.log(Number.isNaN(abc)); // false字符串再像 NaN 也没用✅记住这一点Number.isNaN()只对真正的NaN说“是”其他所有情况都说“不是”。三、为啥推荐用Number上的那两个方法方法会不会自动转类型判断严不严容不容易出错isFinite()会不严❌ 容易误判Number.isFinite()不会严✅ 更安全isNaN()会不严❌ 容易误解Number.isNaN()不会严✅ 更准确在实际写代码的时候比如验证用户输入、处理后台返回的数据、清洗原始信息等用Number.isNaN()能避免把像error这样的字符串当成NaN来处理这样程序就不容易出错也更好理解。四、怎么用才好老浏览器怎么办最好的做法平时就用Number.isNaN()和Number.isFinite()别用全局的那两个。如果要支持老浏览器比如 IE可以自己加一段代码来补上if (!Number.isNaN) { Number.isNaN function(value) { return typeof value number isNaN(value); }; }如果你用 TypeScriptNumber.isNaN还有个好处它能让编辑器知道某个变量现在肯定是NaN帮你减少类型错误。最后说两句JavaScript 很灵活但也正因为太灵活有些老方法比如isNaN和isFinite会悄悄转换类型结果让人意想不到。ES6 加的Number.isNaN和Number.isFinite就是为了修这个问题——它们不乱转类型行为更清楚用起来更放心。作为现在的前端开发者我们应该多用这些新方法写出更简单、更不容易出错的代码。一句话记牢只有原原本本的NaN才能让Number.isNaN()返回 true别的都不行