只是出于好奇 .
typeof NaN
是数字似乎不合逻辑 . 就像 NaN === NaN
或 NaN == NaN
返回false一样 . 这是javascript的特点之一,还是有理由这样做?
编辑:谢谢你的回答 . 尽管让人们感到高兴并不容易 . 阅读答案和维基我理解得更多,但仍然是一句话
与NaN进行比较时,即使与自身进行比较,也会返回无序结果 . 比较谓词是信令或非信令,信令版本表示这种比较的无效例外 . 等式和不等式谓词是非信令的,因此x = x返回false可用于测试x是否是安静的NaN .
只是让我头晕目眩 . 如果有人能用人类(而不是数学家)的可读语言翻译,我会感激不尽 .
20 回答
值NaN实际上是Number.NaN因此当你问它是否是一个数字时它会说是 . 你通过使用isNaN()调用做了正确的事情 .
有关信息,NaN也可以通过对未定义的数字的操作返回,如零或负数的平方根 .
那么,
NaN
仍然是一种数字类型,尽管事实上它实际上代表的是非数字:-)NaN
只是意味着特定值不能在数字类型的限制内表示(尽管可以说所有必须舍入到适合的数字,但NaN
是一种特殊情况) .特定
NaN
不被视为等于另一个NaN
,因为它们可能是不同的值 . 但是,NaN
仍然是数字类型,就像2718或31415一样 .至于您更新的问题,以外行的方式解释:
所有这些意味着(分解为部分):
基本上,
NaN
不等于任何其他数字,包括另一个NaN
,甚至包括它自己 .尝试在
NaN
与另一个数字之间进行比较(小于,大于等)操作可能导致抛出异常(信令)或者仅仅导致结果为假(非信令或安静) .相等(等于,不等于)的测试从不发出信号,因此使用它们不会导致异常 . 如果你有一个常规数字
x
,那么x == x
将永远为真 . 如果x
是NaN
,则x == x
将始终为false . 它为您提供了一种轻松(安静地)检测_2386503的方法 .这意味着不是数字 . 它不是javascript的特性,而是普通的计算机科学原理 .
来自http://en.wikipedia.org/wiki/NaN:
所有这些值可能不一样 . 对NaN的简单测试是测试
value == value
是否为假 .你一定要喜欢Javascript . 它有一些有趣的小怪癖 .
http://wtfjs.com/page/13
如果你停下来逻辑地解决它们,或者如果你对数论有所了解,那么大多数这些怪癖都可以解释,但是如果你不了解它们,它们仍然可以让你知道 .
顺便说一句,我建议阅读http://wtfjs.com/的其余部分 - 有比这个更有趣的怪癖!
ECMAScript(JavaScript)标准指定
Numbers
是IEEE 754浮点数,其中包含NaN
作为可能的值 .typeof NaN
返回'number'
因为:typeof
相应地返回:此行为符合IEEE Standard for Floating-Point Arithmetic (IEEE 754):
NaN是有效的浮点值(http://en.wikipedia.org/wiki/NaN)
和NaN === NaN是假的,因为它们不一定是相同的非数字
NaN != NaN
因为他们不需要SAME非号码 . 因此它很有意义......另外为什么浮点数的0.00和-0.00都不相同 . 舍入可能会使它们实际上不为零 .至于typeof,这取决于语言 . 并且大多数语言会说NaN是浮点数,双精度数或数字取决于它们如何对它进行分类...我知道没有语言可以说这是一个未知类型或null .
NaN
代表Not a Number . 它是数值数据类型的值(通常是浮点类型,但不总是),表示无效操作的结果,例如除以零 .虽然它的名称表示它不是数字,但用于保存它的数据类型是数字类型 . 所以在JavaScript中,要求
NaN
的数据类型将返回number
(如alert(typeof(NaN))
清楚地演示) .Javascript使用NaN来表示它遇到的任何无法通过其规范以任何其他方式表示的内容 . 这并不意味着它不是一个数字 . 这只是描述遭遇的最简单方法 . NaN意味着它或引用它的对象无法通过javascript以任何其他方式表示 . 出于所有实际目的,它是“未知的” . 作为'未知',它无法告诉你它是什么,即使它本身也是如此 . 它甚至不是它所分配的对象 . 它它只能告诉你它不是什么,而且只能用编程语言在数学上描述虚无或虚无 . 由于数学是关于数字的,因此javascript代表NaN的虚无 . 这并不意味着它不是一个数字 . 这意味着我们无法以任何其他有意义的方式阅读它 . 这就是为什么它甚至不能平等 . 因为它没有 .
NaN
的一个更好的名称,更精确,更容易混淆地描述它的含义,将是一个 numerical exception . 它实际上是另一种异常对象,伪装成具有原始类型(通过语言设计),同时它在虚假的自我比较中不被视为原始的 . 从此混乱 . 并且只要语言"will not make its mind"在适当的异常对象和原始数字之间进行选择,就会留下混乱 .==
和===
这两个臭名昭着的非平等本身就是将这个异常对象强制为原始类型的混乱设计的表现形式 . 这打破了 primitive is uniquely determined by its value 的基本原则 . 如果NaN
首选被视为异常(其中可以有不同种类),则它不应该是原始的"sold" . 如果它想成为原始的那个原则必须坚持下去 . 只要它被打破,就像我们在JavaScript中一样,并且我们无法在两者之间做出真正的决定,导致所涉及的每个人的不必要的认知负荷的混乱将保持不变 . 但是,通过简单地在两者之间做出选择,这很容易解决:要么使
NaN
成为一个特殊的异常对象,其中包含有关异常如何产生的有用信息,而不是像当前实现的那样抛弃那些信息,从而导致难以调试的代码;或使
NaN
成为原始类型number
的实体(可能不那么令人困惑地称为"numeric"),在这种情况下它应该等于自身并且不能包含任何其他信息;后者显然是一个低劣的选择 .将
NaN
强制转换为number
类型的唯一可想象的优点是能够将其抛回到任何数值表达式中 . 然而,这使得它变得脆弱,因为包含NaN
的任何数值表达式的结果将是NaN
,或者导致不可预测的结果,例如NaN < 0
评估为false
,即返回boolean
而不是保持异常 .即使“事物就是它们的方式”,也没有什么能阻止我们为自己做出明确的区分,以帮助使我们的代码更易于预测和更容易调试 . 实际上,这意味着识别这些例外并将其作为例外处理 . 不幸的是,这意味着更多的代码,但希望通过Flowtype的TypeScript等工具来缓解这些代码 .
然后我们就有了凌乱的quiet vs noisy aka signalling NaN distinction . 这实际上是关于如何处理异常,而不是异常本身,与其他异常没什么不同 .
类似地,
Infinity
和+Infinity
是extension of the real line中出现的数字类型的元素,但它们不是实数 . 在数学上,它们可以由收敛到+
或-Infinity
的实数序列表示 .这只是因为
NaN
是JS中Number对象的属性,它与数字无关 .想到NAN的最佳方式是它不是 known 数字 . 这就是NAN!= NAN的原因,因为每个NAN值代表一些唯一的未知数字 . NAN是必要的,因为浮点数具有有限的值范围 . 在某些情况下,舍入发生在较低位丢失的地方,这导致看起来像1.0 / 11 * 11!= 1.0的无意义 . 非常大的值是更大的NAN,无限是一个完美的例子 .
鉴于我们只有10个手指,任何显示大于10的值的尝试都是不可能的,这意味着这些值必须是NAN,因为我们已经失去了大于10的值的真实值 . 浮点值也是如此,其中值超出了浮点数的限制 .
NaN
是从类型的角度来看的数字,但不是正常的数字,如1,2或329131.名称 "Not A Number" 指的是表示的值是特殊的,并且是关于IEEE格式规范域,而不是javascript语言域 .如果使用jQuery,我更喜欢
isNumeric
而不是检查类型:http://api.jquery.com/jQuery.isNumeric/
Javascript只有一种数字数据类型,即标准的64位双精度浮点数 . 一切都是双重的 . NaN是double的特殊值,但它仍然是双倍的 .
所有
parseInt
所做的就是"cast"将您的字符串转换为数字数据类型,因此结果总是"number";只有当原始字符串不可解析时,其值才为NaN .Number类型的特殊值为POSITIVE_INFINITY
为什么?按设计
NaN仍然是数字类型,但它表示无法表示有效数字的值 .
因为NaN是数字数据类型 .
我们可以说NaN是一个特殊的案例对象 . 在这种情况下,NaN的对象代表一个没有数学意义的数字 . 数学中还有一些其他特殊情况对象,如INFINITE等 .
您仍然可以使用它进行一些计算,但这会产生奇怪的行为 .
更多信息:http://www.concentric.net/~ttwang/tech/javafloat.htm(基于java,不是javascript)