mdn - javascript是什么




为什么typeof NaN返回'数字'? (14)

只是出于好奇。

typeof NaN是数字似乎并不合逻辑。 就像NaN === NaNNaN == NaN顺便返回false。 这是javascript的特性之一,还是会有这个原因呢?

编辑:谢谢你的答案。 尽管让人头晕目眩并非易事。 阅读答案和维基我了解得更多,但仍然是一个像

与NaN进行比较时,即使与自身进行比较,也总会返回无序的结果。 比较谓词是信令或非信令,信令版本表示这种比较的无效例外。 等式和不等式谓词是非信号的,所以x = x返回false可用于测试x是否是安静的NaN。

只是让我的头转动。 如果有人可以在人类(而不是数学家)可读的语言中翻译这个,我会很乐意。


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

ECMA 262 5e第4.3.19节 :数值

原始值对应于双精度64位二进制格式IEEE 754值。

ECMA 262 5e第4.3.23节 :NaN

数值是IEEE 754“非数字”值。

维基百科上的IEEE 754

IEEE标准浮点算法是电气和电子工程师协会制定的技术标准,也是浮点运算最广泛使用的标准[...]

标准定义

  • 算术格式 :由有限数字(包括带符号的零和次正数),无穷大和特殊的“非数字”值(NaN)组成的二进制和十进制浮点数据集,

[...]


JavaScript只有一种数字数据类型,它是标准的64位双精度浮点数。 一切都是双重的。 NaN是双倍的特殊价值,但它仍然是双倍的。

parseInt所做的一切就是将您的字符串“转换”为数字数据类型,因此结果始终为 “数字”。 只有当原始字符串不可解析时,其值才是NaN。


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



NaN != NaN因为它们不需要相同的非数字。 因此它有很大的意义......同样为什么花车有+0.00和-0.00不一样。 舍入可能会做,他们实际上不是零。

至于typeof,则取决于语言。 大多数语言都会说NaN是浮点数,双精度数或数字,这取决于它们如何分类......我知道没有语言会说这是一个未知类型或null。


NaN一个更好的名称,更准确地描述其含义并且不那么容易混淆,这将是一个数值例外 。 它实际上是另一种被伪装成具有原始类型(通过语言设计)的异常对象,其中在相同的情况下,它不被视为原始的虚假自我比较。 从哪里混乱。 只要语言“无法自行决定”在适当的例外对象原始数字之间做出选择,混淆就会停滞不前。

NaN自身的臭名昭着的不等同, =====都是令人困惑的设计的表现,强制这个异常对象成为一种原始类型。 这打破了一个基本原则,即基元是由其价值独一无二地决定的 。 如果NaN被认为是例外(其中可能有不同的种类),那么它不应该被当作原始的“出售”。 如果它想成为原始的,那么这个原则必须成立。 只要它被打破了,就像我们在JavaScript中所做的一样,而且我们无法在两者之间做出真正的决定,那么导致所有相关人员不必要的认知负担的混淆依然存在。 然而,通过简单地在两者之间做出选择,它确实很容易解决:

  • 要么让NaN成为一个特殊的异常对象,其中包含有关如何产生异常的有用信息,而不是像当前实现的那样丢弃那些信息,导致难以调试的代码;
  • 或者使NaN成为原始类型number的实体(可能不那么容易被称为“数字”),在这种情况下,它应该与自身相同并且不能包含任何其他信息; 后者显然是劣等的选择。

强制NaN进入number类型的唯一可能的好处是能够将其重新用于任何数字表达式。 然而,这使得它变得很脆弱,因为任何包含NaN数字表达式的结果都是NaN ,或者导致不可预知的结果,例如NaN < 0评估为false ,即返回boolean而不是保持异常。

即使“事情是他们的样子”,没有什么能够阻止我们为自己做出明确的区分,帮助我们的代码更具可预测性,更容易调试。 实际上,这意味着确定这些例外情况并将其作为例外处理。 不幸的是,这意味着更多的代码,但希望可以通过诸如Flowtype的TypeScript之类的工具来缓解。

然后,我们有了凌乱的安静与嘈杂的又名信号NaN区别 。 究竟是如何处理异常,而不是异常本身,与其他异常没有什么不同。

类似地, Infinity+Infinity数字类型的元素,它们出现在实线扩展中,但它们不是实数。 在数学上,它们可以用收敛于+-Infinity的实数序列表示。


NaN是从类型角度来看的一个数字,但不是像1,2或329131这样的正常数字。名称“不是数字”是指所表示的值是特殊的并且是关于IEEE格式规范域的事实,不是JavaScript语言域。


typeof NaN返回'number'因为:

  • ECMAScript规范说数字类型包括NaN:

    4.3.20号码类型

    包括特殊的“非数字”(NaN)值,正无限和负无穷的所有可能的数值集

  • 所以typeof返回:

    11.4.3操作员的类型

    生产UnaryExpressiontypeof UnaryExpression的计算方法如下:

    1. val是评估UnaryExpression的结果。
    2. 如果Typeval )是Reference ,那么
      1. 如果Referenceval )为true ,则返回"undefined"
      2. val成为GetValueval )。
    3. 根据表20返回Typeval )确定的字符串。

                    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数字值

原始值对应于双精度64位二进制格式IEEE 754值

4.3.23 NaN

数字值是IEEE 754“非数字”值

8.5数字类型

Number类型正好具有18437736874454810627(即2 53 -2 64 +3)个值,表示双精度64位格式IEEE 754值,如IEEE二进制浮点算法标准中所指定的,不同之处在于9007199254740990(即2 53 -2)IEEE标准中不同的“非数字”值在ECMAScript中表示为单个特殊的NaN值。 (请注意, NaN值由程序表达式NaN 。)


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

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

api.jquery.com/jQuery.isNumeric


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

来自http://en.wikipedia.org/wiki/NaN

有三种返回NaN的操作:

将NaN作为至少一个操作数进行操作

不确定的形式

  • 划分0/0,∞/∞,∞/-∞,-∞/∞和-∞/-∞
  • 乘法运算0×∞和0×∞
  • 功率1 ^∞
  • 加法∞+(-∞),(-∞)+∞和等价减法。

真实的操作和复杂的结果:

  • 负数的平方根
  • 负数的对数
  • 90度(或π/ 2弧度)的奇数倍的正切值
  • 数字的反正弦或余弦小于-1或大于+1。

所有这些值可能不一样。 NaN的简单测试是测试value == value false。


想想NAN的最佳方式是它不是已知的数字。 这就是为什么NA​​N!= NAN,因为每个NAN值代表一些唯一的未知数。 NAN是必需的,因为浮点数的值范围有限。 在某些情况下,舍入发生在低位丢失的地方,这导致似乎是无意义的,如1.0 / 11 * 11!= 1.0。 无限大的NAN是一个很好的例子。

由于我们只有十根手指,所以试图显示大于10的值是不可能的,这意味着这些值必须是NAN,因为我们已经失去了大于10的值的真值。 浮点值也是如此,其中的值超过了浮点数的限制。



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


那么, NaN仍然是一个数字类型 ,尽管它实际上代表了Not-A-Number :-)

NaN只是意味着特定的值不能在数字类型的限制范围内表示(尽管对于所有必须进行四舍五入的数字都可以这样说,但NaN是一种特殊情况)。

特定的NaN不被认为与另一个NaN相等,因为它们可能是不同的值。 但是, NaN仍然是一个数字类型,就像2718或31415。

至于你更新的问题,以外行的话来解释:

与NaN进行比较时,即使与自身进行比较,也总会返回无序的结果。 比较谓词是信令或非信令,信令版本表示这种比较的无效例外。 等式和不等式谓词是非信号的,所以x = x返回false可用于测试x是否是安静的NaN。

所有这些意思是(分解成部分):

与NaN进行比较时,即使与自身进行比较,也总会返回无序的结果。

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

比较谓词是信令或非信令,信令版本表示这种比较的无效例外。

试图在NaN和另一个号码之间进行比较(小于,大于等)操作可能会导致抛出异常(信号传递)或仅仅因为结果(非信令或安静)而导致错误。

等式和不等式谓词是非信号的,所以x = x返回false可用于测试x是否是安静的NaN。

对相等(等于,不等于)的测试永远不会发出信号,所以使用它们不会引起异常。 如果您有一个常规数字x ,那么x == x将始终为真。 如果x是一个NaN ,那么x == x将始终为假。 它为您提供了一种轻松(安静地)检测NaN的方法。





javascript