Why does typeof NaN return 'number'?

前端 未结 21 1214
误落风尘
误落风尘 2020-11-22 05:38

Just out of curiosity.

It doesn\'t seem very logical that typeof NaN is number. Just like NaN === NaN or NaN == NaN returning

相关标签:
21条回答
  • 2020-11-22 06:17

    NaN stands for Not a Number. It is a value of numeric data types (usually floating point types, but not always) that represents the result of an invalid operation such as dividing by zero.

    Although its names says that it's not a number, the data type used to hold it is a numeric type. So in JavaScript, asking for the datatype of NaN will return number (as alert(typeof(NaN)) clearly demonstrates).

    0 讨论(0)
  • 2020-11-22 06:18

    An example

    Imagine We are converting a string to a number:

    Number("string"); // returns NaN
    

    We changed the data type to number but its value is not a number!

    0 讨论(0)
  • 2020-11-22 06:20

    typeof NaN returns 'number' because:

    • 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:

      1. Let val be the result of evaluating UnaryExpression.
      2. If Type(val) is Reference, then
        1. If IsUnresolvableReference(val) is true, return "undefined".
        2. Let val be GetValue(val).
      3. 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".            |
      ------------------------------------------------------------------
      

    This behavior is in accordance with IEEE Standard for Floating-Point Arithmetic (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.)

    0 讨论(0)
  • 2020-11-22 06:21

    It means Not a Number. It is not a peculiarity of javascript but common computer science principle.

    From 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.

    All these values may not be the same. A simple test for a NaN is to test value == value is false.

    0 讨论(0)
  • 2020-11-22 06:21

    NaN != NaN because they are not necessary the SAME non-number. Thus it makes a lot of sense... Also why floats have both +0.00 and -0.00 that are not the same. Rounding may do that they are actually not zero.

    As for typeof, that depends on the language. And most languages will say that NaN is a float, double or number depending on how they classify it... I know of no languages that will say this is an unknown type or null.

    0 讨论(0)
  • 2020-11-22 06:22

    Well, it may seem a little strange that something called "not a number" is considered a number, but NaN is still a numeric type, despite that fact :-)

    NaN just means the specific value cannot be represented within the limitations of the numeric type (although that could be said for all numbers that have to be rounded to fit, but NaN is a special case).

    A specific NaN is not considered equal to another NaN because they may be different values. However, NaN is still a number type, just like 2718 or 31415.


    As to your updated question to explain in layman's terms:

    A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.

    All this means is (broken down into parts):

    A comparison with a NaN always returns an unordered result even when comparing with itself.

    Basically, a NaN is not equal to any other number, including another NaN, and even including itself.

    The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons.

    Attempting to do comparison (less than, greater than, and so on) operations between a NaN and another number can either result in an exception being thrown (signalling) or just getting false as the result (non-signalling or quiet).

    The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.

    Tests for equality (equal to, not equal to) are never signalling so using them will not cause an exception. If you have a regular number x, then x == x will always be true. If x is a NaN, then x == x will always be false. It's giving you a way to detect NaN easily (quietly).

    0 讨论(0)
提交回复
热议问题