NaN是否等于NaN?

55
parseFloat("NaN")
返回“NaN”,但是。
parseFloat("NaN") == "NaN"

返回 false 值。这样做可能是有好处的,但我不明白为什么会这样。JavaScript 的创建者是否将其作为一个特殊情况来处理?否则我就不理解为什么会返回 false。


22
根据定义,NaN永远不等于它自己。这适用于任何语言。 - Keith
1
请注意:在ECMAScript 6中,已经添加了一种精确的检查方法,请参考我的下面回答 - krillgar
1
事件的最佳部分是 parseFloat("A") == parseFloat("A") 返回 false - Mariusz Jamro
1
@MariuszJamro 这是因为 parseFloat("A") 在每个一侧都返回 NaN。正如其他答案所述,NaN 甚至不等于它自己。 - krillgar
parseFloat("NaN") == NaN <-- 这是一个比较有趣的问题(不包括引号)。仍然不行。NaN 是有毒的。请使用 isNaN() - Bob Stein
8个回答

41

更新2

ECMAScript 6中新增了Object.is()函数。该函数旨在进一步增强 === 检查。这个新功能的好处之一是, Object.is(NaN,NaN)现在将返回true。如果您能够使用ECMAScript 6, 那么这将是最可读和一致的解决方案。

原文

检查这个的正确方法是:

isNaN(parseInt(variable))

如果你要检查的内容是 NaN,该函数将返回 true。这个方法已经内置在 JavaScript 规范中。
使用 jQuery
jQuery 最初构建了自己的 isNaN 函数来帮助解决浏览器之间的一些差异,并添加了一些额外的检查,使其版本可以替代 VanillaJS 中的版本。
jQuery 更新
在 jQuery 1.7 之后,他们将这个函数更改为 $.isNumeric()切换文档 如果你看一下 此 Stack Overflow 问题,你会发现有很多时候 isNaN() 返回的答案会直观地被认为是“不正确”的,但在规范上是正确的。
避免使用原生的 isNaN() 的一个主要原因是,null 会返回 false,这会让你认为它是一个数字。然而,jQuery 函数涵盖了更广泛的直觉结果。
根据它们的文档:
自 jQuery 3.0 起,仅当参数为数字类型或为字符串类型且可以强制转换为有限数值时,$.isNumeric() 才返回 true。在所有其他情况下,它都返回 false。

12
这与jQuery无关。什么? - user1596138
仅仅因为jQuery改变了他们使用的函数并不意味着你也必须这样做。 - John Dvorak
parseInt()parseFloat()存在一个相当严重的问题,即它们会接受出现在有效数字之后的“垃圾”字符。 - Pointy

38

25
NaN不是一个对象,它是一个特殊的原始值(恰好是全局对象中一个只读属性的值)。 - hmakholm left over Monica

37

这是一个特殊情况,NaN是JavaScript中唯一不等于自身的东西。

虽然关于字符串与NaN对象的其他答案也是正确的。


1
为什么 "NaN" == "NaN" 的结果是 true 呢?如果返回 false 的话可能没有意义,但是... - joseph
32
@joseph "NaN" == "NaN"是在比较两个(相等)的字符串。 - dlev

12

NaN 是唯一一个不等于自身的对象之一。事实上,这个特性被用来实现常见的 bool IsNaN(number) 方法:

function isNaN(x)
{ 
    return x != x; 
}

7
那看起来很有趣的 javascript - Lee Taylor
3
将示例从 C# 更改为 JavaScript。 - Martin Devillers
2
有几个例子吗?如果有的话,这种实现在那些其他例子上会失败。 - djechlin
“NaN”根本不是对象,而是一个类型为数字的常量。 - Pointy

9

isNaN适用于所有不是数字的值。

isNaN('foo') == true // a string is indeed not a number
isNaN(NaN) == true
isNaN(12) == false
isNaN([1,2,3]) == true // an array is also not a number

如果您想检查特定的NaN,或避免类型转换;
您可以使用Number.isNaN

Number.isNaN('foo') == false
Number.isNaN(NaN) == true
Number.isNaN(12) == false
Number.isNaN([1,2,3]) == false

8
  • Number(由ParseFloat返回)与转换为Numberstring进行比较时
  • NaN不等于任何其他对象(包括NaN

你得到了NaN==NaN。根据第二条规则,它是错误的。


1
在ECMAScript 6中,Object.is()是===的一个增强版本。该方法接受两个参数,如果这两个值等价,则返回true。当它们具有相同的类型和相同的值时,这两个值被视为等价。这就是为什么console.log(Object.is(NaN, NaN))--> TRUE的原因。

0

我正在使用Google Apps Script,因此我被困在ECMA 5中。与Electric Coffee的答案类似,这是我能够找出的似乎可以确定一个值是否实际上是NaN,而不是一个值是否是NaN本身:

function isThisNaN(x)
{ 
    return isNaN(x) && Object.prototype.toString.call(x) === '[object Number]'; 
}
console.log(isThisNaN(NaN)); // true

哈哈,我觉得很有趣,Object.prototype.toString.call(NaN) 等于 '[object Number]'。我的新手脑袋告诉我,NaN 是“不是一个数字”,但可悲的是它并不那么简单。

编辑: 我想我应该说一下我是怎么找到这篇文章的。我认为一个不包含数字的字符串肯定不会被视为数字...好吧,我最终发现了这个:

isNaN('a'); // true
isNaN(' '); // false

所以即使 ' ' 是一个非数字字符串,它似乎也被强制转换为数字 (0)。

console.log(Number(' ')); // 0.0

然而...

console.log( 0  ? true : false); // false
console.log(' ' ? true : false); // true

读了更多之后,我有点理解了,但对于新手来说,这真是一场脑力风暴。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接