只是出于好奇。

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

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

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

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


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

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


好吧,这似乎有点奇怪,所谓的“不是一个数字”被认为是一个数字,但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的方法。


这只是因为NaN是JS中Number对象的一个属性,它与它是否是一个数字无关。


它的意思是不是一个数字。这不是javascript的特性,而是常见的计算机科学原理。

从http://en.wikipedia.org/wiki/NaN:

There are three kinds of operation which return NaN: Operations with a NaN as at least one operand Indeterminate forms The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞ The multiplications 0×∞ and 0×−∞ The power 1^∞ The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions. Real operations with complex results: The square root of a negative number The logarithm of a negative number The tangent of an odd multiple of 90 degrees (or π/2 radians) The inverse sine or cosine of a number which is less than −1 or greater than +1.

所有这些值可能都不相同。NaN的一个简单测试是测试value == value为false。


NaN是一个有效的浮点值(http://en.wikipedia.org/wiki/NaN)

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


考虑NAN的最好方法是它不是一个已知的数字。这就是为什么NAN != NAN,因为每个NAN值代表一个唯一的未知数字。nan是必要的,因为浮点数的值范围有限。在某些情况下,舍去小数位会丢失,导致出现像1.0/11*11 != 1.0这样的无意义的结果。真正大的值是nan,无穷大就是一个很好的例子。

鉴于我们只有十个手指,任何显示大于10的值的尝试都是不可能的,这意味着这些值必须是nan,因为我们已经丢失了这个大于10的值的真实值。浮点值也是如此,其值超过了浮点数所能容纳的限制。


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

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


它是Number类型的特殊值,如POSITIVE_INFINITY

为什么?通过设计


NaN代表Not a Number。它是数值型数据类型(通常是浮点型,但不总是)的值,表示无效操作(如除零)的结果。

尽管它的名称表明它不是数字,但用于保存它的数据类型是数字类型。因此在JavaScript中,请求NaN的数据类型将返回number(正如alert(typeof(NaN))清楚地演示的那样)。


NaN仍然是数字类型,但它表示不能表示有效数字的值。


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


ECMAScript (JavaScript)标准指定数字为IEEE 754浮点数,其中包括NaN作为可能的值。

ECMA 262 5e Section 4.3.19:数字值 原语值对应于双精度64位二进制格式IEEE 754值。

ECMA 262 5e Section 4.3.23: NaN 数字值,它是IEEE 754“非数字”值。

维基百科上的IEEE 754 IEEE浮点算术标准是由电气和电子工程师协会建立的技术标准,也是浮点计算最广泛使用的标准[…] 标准定义了 算术格式:二进制和十进制浮点数据集,由有限数(包括有符号的零和次正规数)、无穷大和特殊的“非数字”值(nan)组成 […]


从类型的角度来看,NaN是一个数字,但不是像1、2或329131这样的普通数字。“不是一个数字”的名字指的是表示的值是特殊的,是关于IEEE格式规范领域,而不是javascript语言领域。


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

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

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


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

http://wtfjs.com/page/13

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

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


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

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


Javascript uses NaN to represent anything it encounters that can't be represented any other way by its specifications. It does not mean it is not a number. It's just the easiest way to describe the encounter. NaN means that it or an object that refers to it could not be represented in any other way by javascript. For all practical purposes, it is 'unknown'. Being 'unknown' it cannot tell you what it is nor even if it is itself. It is not even the object it is assigned to. It can only tell you what it is not, and not-ness or nothingness can only be described mathematically in a programming language. Since mathematics is about numbers, javascript represents nothingness as NaN. That doesn't mean it's not a number. It means we can't read it any other way that makes sense. That's why it can't even equal itself. Because it doesn't.


如果使用jQuery,我更喜欢isNumeric检查类型:

console.log($.isNumeric(NaN));  // returns false
console.log($.type(NaN));       // returns number

http://api.jquery.com/jQuery.isNumeric/


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

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是出现在实数线扩展中的数字类型元素,但它们不是实数。在数学上,它们可以用收敛到正无穷或负无穷的实数序列来表示。


一个例子

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

Number("string"); // returns NaN

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