只是出于好奇。

typeof NaN是number似乎不太符合逻辑。就像NaN === NaN或NaN == NaN返回false。这是JavaScript的特性之一吗,或者有什么原因吗?

编辑:谢谢你的回答。然而,让人明白这不是一件容易的事情。阅读答案和维基我明白了更多,但仍然,一句话像

与NaN的比较总是返回无序结果,即使是与NaN本身比较也是如此。比较谓词是信号或非信号,信号版本表示此类比较的无效异常。等式和不等式谓词是非信号,因此x = x返回false可用于测试x是否为静态NaN。

让我头晕目眩。如果有人能把它翻译成人类(而不是数学家)可读的语言,我会很感激。


当前回答

NaN的一个更好的名称应该是一个数值例外,它更准确地描述了它的含义,而且不那么容易混淆。它实际上是另一种伪装成具有原始类型的异常对象(通过语言设计),同时它在错误的自我比较中不被视为原始类型。这就是困惑。只要语言“不下定决心”在适当的例外对象和原始数之间进行选择,这种混乱就会存在。

The infamous non-equality of NaN to itself, both == and === is a manifestation of the confusing design forcing this exception object into being a primitive type. This breaks the fundamental principle that a primitive is uniquely determined by its value. If NaN is preferred to be seen as exception (of which there can be different kinds), then it should not be "sold" as primitive. And if it is wanted to be primitive, that principle must hold. As long as it is broken, as we have in JavaScript, and we can't really decide between the two, the confusion leading to unnecessary cognitive load for everyone involved will remain. Which, however, is really easy to fix by simply making the choice between the two:

要么使NaN成为一个特殊的异常对象,其中包含有关异常如何产生的有用信息,而不是将当前实现的信息丢弃,导致更难调试的代码; 或者让NaN成为一个基本类型为number的实体(称为“numeric”不那么容易混淆),在这种情况下,它应该等于自身,不能包含任何其他信息;后者显然是一个较差的选择。

将NaN强制转换为数字类型的唯一可以想象的好处是能够将其扔回任何数值表达式中。然而,这使得它成为脆弱的选择,因为任何包含NaN的数值表达式的结果都将是NaN,或者导致不可预测的结果,例如NaN < 0求值为false,即返回布尔值而不是保持异常。

即使“事情就是这样”,也没有什么能阻止我们为自己做出明确的区分,以帮助我们的代码更可预测,更容易调试。在实践中,这意味着识别这些异常并将其作为异常处理。不幸的是,这意味着更多的代码,但希望通过Flowtype的TypeScript等工具来缓解。

然后我们有混乱的安静和嘈杂,即信号NaN的区别。这实际上是关于如何处理异常,而不是异常本身,与其他异常没有什么不同。

类似地,Infinity和+Infinity是出现在实数线扩展中的数字类型元素,但它们不是实数。在数学上,它们可以用收敛到正无穷或负无穷的实数序列来表示。

其他回答

好吧,这似乎有点奇怪,所谓的“不是一个数字”被认为是一个数字,但NaN仍然是一个数字类型,尽管事实如此:-)

NaN仅仅意味着特定的值不能在数字类型的限制范围内表示(尽管这可以说是所有必须四舍五入以适应的数字,但NaN是一个特殊情况)。

一个特定的NaN不等同于另一个NaN,因为它们可能是不同的值。然而,NaN仍然是一种数字类型,就像2718或31415一样。


至于你更新的问题,用外行的话解释一下:

与NaN的比较总是返回无序结果,即使是与NaN本身比较也是如此。比较谓词是信号或非信号,信号版本表示此类比较的无效异常。等式和不等式谓词是无信号的,因此x = x返回false可用于测试x是否为静态NaN。

所有这一切的意思是(分解为几个部分):

与NaN的比较总是返回无序结果,即使是与NaN本身比较也是如此。

基本上,一个NaN不等于任何其他数字,包括另一个NaN,甚至包括它自己。

比较谓词是信号或非信号,信号版本表示此类比较的无效异常。

试图在一个NaN和另一个数字之间进行比较(小于、大于等)操作,可能导致抛出异常(发出信号),也可能导致结果为false(非发出信号或为quiet)。

等式和不等式谓词是无信号的,因此x = x返回false可用于测试x是否为静态NaN。

相等(等于,不等于)的测试永远不会发出信号,因此使用它们不会导致异常。如果有一个正则数x,那么x == x总是成立的。如果x是一个NaN,那么x == x将永远是假的。它为您提供了一种轻松(悄悄)检测NaN的方法。

你必须热爱Javascript。它有一些有趣的小怪癖。

http://wtfjs.com/page/13

如果你停下来从逻辑上算出这些怪癖,或者如果你知道一点数论,大多数怪癖都可以解释清楚,但如果你不知道它们,它们仍然会让你出错。

顺便说一下,我建议你阅读http://wtfjs.com/的其余部分——还有很多比这个更有趣的怪癖!

Javascript只有一种数字数据类型,即标准的64位双精度浮点数。所有东西都是双的。NaN是double的特殊值,但它仍然是double。

所有parseInt所做的是将字符串“转换”为数值数据类型,因此结果总是“number”;只有当原始字符串不可解析时,它的值才会是NaN。

因为NaN是数值型数据类型。

NaN值实际上是Number。因此,当你问它是否是一个数字时,它会说是的。使用isNaN()调用是正确的。

作为信息,NaN也可以通过对未定义的数字(如除零或负数的平方根)的操作返回。