只是出于好奇。

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是一个有效的浮点值(http://en.wikipedia.org/wiki/NaN)

NaN === NaN为假,因为它们不一定是相同的非数字

一个例子

假设我们正在将一个字符串转换为一个数字:

Number("string"); // returns NaN

我们将数据类型更改为数字,但它的值不是数字!

NaN != NaN,因为它们不是相同的非数字。因此……很有道理。 浮点数+0.00和-0.00不一样的原因。四舍五入可以做到它们实际上不为零。

至于typeof,这取决于语言。大多数语言会说NaN是浮点数、双精度数或数字,这取决于他们如何对它进行分类……据我所知,没有一种语言会说这是未知类型或null。

typeof NaN返回'number',因为:

ECMAScript spec says the Number type includes NaN: 4.3.20 Number type set of all possible Number values including the special “Not-a-Number” (NaN) values, positive infinity, and negative infinity So typeof returns accordingly: 11.4.3 The typeof Operator The production UnaryExpression : typeof UnaryExpression is evaluated as follows: Let val be the result of evaluating UnaryExpression. If Type(val) is Reference, then If IsUnresolvableReference(val) is true, return "undefined". Let val be GetValue(val). Return a String determined by Type(val) according to Table 20. ​ Table 20 — typeof Operator Results ================================================================== | Type of val | Result | ================================================================== | Undefined | "undefined" | |----------------------------------------------------------------| | Null | "object" | |----------------------------------------------------------------| | Boolean | "boolean" | |----------------------------------------------------------------| | Number | "number" | |----------------------------------------------------------------| | String | "string" | |----------------------------------------------------------------| | Object (native and does | "object" | | not implement [[Call]]) | | |----------------------------------------------------------------| | Object (native or host and | "function" | | does implement [[Call]]) | | |----------------------------------------------------------------| | Object (host and does not | Implementation-defined except may | | implement [[Call]]) | not be "undefined", "boolean", | | | "number", or "string". | ------------------------------------------------------------------

此行为符合IEEE浮点运算标准(IEEE 754):

4.3.19 Number value primitive value corresponding to a double-precision 64-bit binary format IEEE 754 value 4.3.23 NaN number value that is a IEEE 754 “Not-a-Number” value 8.5 The Number Type The Number type has exactly 18437736874454810627 (that is, 253−264+3) values, representing the double-precision 64-bit format IEEE 754 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9007199254740990 (that is, 253−2) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special NaN value. (Note that the NaN value is produced by the program expression NaN.)

我们可以认为NaN是一个特殊情况对象。在本例中,NaN的对象表示一个没有数学意义的数字。数学中还有一些特殊情况的对象,比如INFINITE等等。

你仍然可以用它做一些计算,但这会产生奇怪的行为。

更多信息在这里:http://www.concentric.net/~ttwang/tech/javafloat.htm(基于java,不是javascript)