• JavaScript
  • JavaScript
  • Tutorials and guides
  • Beginner's tutorials
    1. JavaScript Guide
      1. Loops and iteration
      2. Representing dates & times
      3. Working with objects
      4. Iterators and generators
      5. Asynchronous JavaScript
      6. Equality comparisons and sameness
      7. Meta programming
      8. AggregateError
      9. AsyncGenerator
      10. BigInt
      11. DataView
      12. encodeURI()
      13. escape() Deprecated
      14. Float16Array
      15. Generator
      16. Int8Array
      17. InternalError Non-standard
      18. Iterator
      19. NaN
      20. parseInt()
      21. ReferenceError
      22. SharedArrayBuffer
      23. Temporal Experimental
      24. Uint8ClampedArray
      25. unescape() Deprecated
      26. WeakSet
  • Assignment (=)
  • Bitwise AND (&)
  • Bitwise OR assignment (|=)
  • Comma operator (,)
  • Destructuring
  • Exponentiation (**)
  • Greater than (>)
  • import.meta.resolve()
  • Inequality (!=)
  • Less than (<)
  • Logical NOT (!)
  • Multiplication assignment (*=)
  • Nullish coalescing assignment (??=)
  • Optional chaining (?.)
  • Right shift (>>)
  • Strict inequality (!==)
  • this
  • Unsigned right shift (>>>)
  • yield*
  • Block statement
  • continue
  • export
  • for...in
  • if...else
  • let
  • try...catch
  • with Deprecated
  • get
  • The arguments object
    1. callee Deprecated
    2. extends
    3. Static initialization blocks
  • Character class escape: \d, \D, \w, \W, \s, \S
  • Input boundary assertion: ^, $
  • Modifier: (?ims-ims:...)
  • Quantifier: *, +, ?, {n}, {n,}, {n,m}
  • Errors
    1. RangeError: argument is not a valid code point
    2. RangeError: invalid array length
    3. RangeError: repeat count must be less than infinity
    4. ReferenceError: assignment to undeclared variable "x"
    5. SyntaxError: 'arguments'/'eval' can't be defined or assigned to in strict mode code
    6. SyntaxError: \ at end of pattern
    7. SyntaxError: await is only valid in async functions, async generators and modules
    8. SyntaxError: continue must be inside loop
    9. SyntaxError: function statement requires a name
    10. SyntaxError: identifier starts immediately after numeric literal
    11. SyntaxError: invalid assignment left-hand side
    12. SyntaxError: invalid class set operation in regular expression
    13. SyntaxError: invalid property name in regular expression
    14. SyntaxError: invalid unicode escape in regular expression
    15. SyntaxError: missing ) after argument list
    16. SyntaxError: missing } after property list
    17. SyntaxError: missing variable name
    18. SyntaxError: numbers out of order in {} quantifier.
    19. SyntaxError: property name __proto__ appears more than once in object literal
    20. SyntaxError: rest parameter may not have a default
    21. SyntaxError: super() is only valid in derived class constructors
    22. SyntaxError: unlabeled break must be inside loop or switch
    23. TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed
    24. TypeError: "x" is not a function
    25. TypeError: BigInt value can't be serialized in JSON
    26. TypeError: can't convert BigInt to number
    27. TypeError: can't redefine non-configurable property "x"
    28. TypeError: class constructors must be invoked with 'new'
    29. TypeError: Initializing an object twice is an error with private fields/methods
    30. TypeError: Iterator/AsyncIterator constructor can't be used directly
    31. TypeError: property "x" is non-configurable and can't be deleted
    32. TypeError: X.prototype.y called on incompatible type
    33. JavaScript technologies overview
    34. Strict mode
    35. Learn more
    36. See full compatibility
  • The NaN global property is a value representing Not-A-Number.

    Try it

    function sanitize(x) {
      if (isNaN(x)) {
        return NaN;
      }
      return x;
    }
    
    console.log(sanitize("1"));
    / Expected output: "1"
    
    console.log(sanitize("NotANumber"));
    / Expected output: NaN
    

    Value

    The same number value as Number.NaN.

    Property attributes of NaN
    Writableno
    Enumerableno
    Configurableno

    Description

    NaN is a property of the global object. In other words, it is a variable in global scope.

    In modern browsers, NaN is a non-configurable, non-writable property. Even when this is not the case, avoid overriding it.

    There are five different types of operations that return NaN:

    • Failed number conversion (e.g., explicit ones like parseInt("blabla"), Number(undefined), or implicit ones like Math.abs(undefined))
    • Math operation where the result is not a real number (e.g., Math.sqrt(-1))
    • Indeterminate form (e.g., 0 * Infinity, 1 ** Infinity, Infinity / Infinity, Infinity - Infinity)
    • A method or expression whose operand is or gets coerced to NaN (e.g., 7 ** NaN, 7 * "blabla") — this means NaN is contagious
    • Other cases where an invalid value is to be represented as a number (e.g., an invalid Date new Date("blabla").getTime(), "".charCodeAt(1))

    NaN and its behaviors are not invented by JavaScript. Its semantics in floating point arithmetic (including that NaN !== NaN) are specified by IEEE 754. NaN's behaviors include:

    • If NaN is involved in a mathematical operation (but not bitwise operations), the result is usually also NaN. (See counter-example below.)
    • When NaN is one of the operands of any relational comparison (>, <, >=, <=), the result is always false.
    • NaN compares unequal (via !==) to any other value — including to another NaN value.

    NaN is also one of the isNaN() to most clearly determine whether a value is NaN — or, since NaN is the only value that compares unequal to itself, you can perform a self-comparison like x !== x.

    js
    NaN === NaN; / false
    Number.NaN === NaN; / false
    isNaN(NaN); / true
    isNaN(Number.NaN); / true
    Number.isNaN(NaN); / true
    
    function valueIsNaN(v) {
      return v !== v;
    }
    valueIsNaN(1); / false
    valueIsNaN(NaN); / true
    valueIsNaN(Number.NaN); / true
    

    However, do note the difference between isNaN() and Number.isNaN(): the former will return true if the value is currently NaN, or if it is going to be NaN after it is coerced to a number, while the latter will return true only if the value is currently NaN:

    js
    isNaN("hello world"); / true
    Number.isNaN("hello world"); / false
    

    For the same reason, using a BigInt value will throw an error with isNaN() and not with Number.isNaN():

    js
    isNaN(1n); / TypeError: Conversion from 'BigInt' to 'number' is not allowed.
    Number.isNaN(1n); / false
    

    Additionally, some array methods cannot find NaN, while others can. Namely, the index-finding ones (includes()) can:

    js
    const arr = [2, 4, NaN, 12];
    arr.indexOf(NaN); / -1
    arr.includes(NaN); / true
    
    / Methods accepting a properly defined predicate can always find NaN
    arr.findIndex((n) => Number.isNaN(n)); / 2
    

    For more information about NaN and its comparison, see typed arrays.

    js
    const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
    const b2f = (x) => new Float64Array(x.buffer)[0];
    / Get a byte representation of NaN
    const n = f2b(NaN);
    const m = f2b(NaN);
    / Change the sign bit, which doesn't matter for NaN
    n[7] += 2 ** 7;
    / n[0] += 2**7; for big endian processors
    const nan2 = b2f(n);
    console.log(nan2); / NaN
    console.log(Object.is(nan2, NaN)); / true
    console.log(f2b(NaN)); / Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
    console.log(f2b(nan2)); / Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 255]
    / Change the first bit, which is the least significant bit of the mantissa and doesn't matter for NaN
    m[0] = 1;
    / m[7] = 1; for big endian processors
    const nan3 = b2f(m);
    console.log(nan3); / NaN
    console.log(Object.is(nan3, NaN)); / true
    console.log(f2b(NaN)); / Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
    console.log(f2b(nan3)); / Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]
    

    Silently escaping NaN

    NaN propagates through mathematical operations, so it's usually sufficient to test for NaN once at the end of calculation to detect error conditions. The only case where NaN gets silently escaped is when using exponentiation with an exponent of 0, which immediately returns 1 without testing the base's value.

    js
    NaN ** 0 === 1; / true
    

    Specifications

    Specification
    ECMAScript® 2026 Language Specification
    # sec-value-properties-of-the-global-object-nan

    Browser compatibility

    See also