In JavaScript, NaN stands for “Not a Number”. It’s a special value that represents an unrepresentable or undefined numerical result. NaN is a property of the global object, and it’s also considered a type of number in JavaScript, which might seem counterintuitive at first.

NaN is typically the result of operations that should return a number but can’t produce a meaningful numerical value. For example:

Example Code

let result = 0 / 0;
console.log(result); // Output: NaN

In this case, dividing zero by zero is mathematically undefined, so JavaScript returns NaN. One peculiar property of NaN is that it’s not equal to anything, including itself:

console.log(NaN === NaN); // Output: false

This unique behavior makes it challenging to check if a value is NaN using standard comparison operators. To address this, JavaScript provides the isNaN() function. The isNaN() function property is used to determine whether a value is NaN or not. However, it’s important to understand how isNaN() works, as it can sometimes produce unexpected results. Here’s how isNaN() behaves:

console.log(isNaN(NaN));       // true
console.log(isNaN(undefined)); // true
console.log(isNaN({}));        // true
 
console.log(isNaN(true));      // false
console.log(isNaN(null));      // false
console.log(isNaN(37));        // false
 
console.log(isNaN("37"));      // false: "37" is converted to 37
console.log(isNaN("37.37"));   // false: "37.37" is converted to 37.37
console.log(isNaN(""));        // false: empty string is converted to 0
console.log(isNaN(" "));       // false: string with a space is converted to 0
 
console.log(isNaN("blabla"));  // true: "blabla" is not a number

As you can see, isNaN() first attempts to convert the parameter to a number. If it can’t be converted, it returns true. This behavior can lead to some surprising results, especially when dealing with strings that can be coerced into numbers.

Due to these potential inconsistencies, ES6 introduced Number.isNaN(). This method does not attempt to convert the parameter to a number before testing. It only returns true if the value is exactly NaN:

console.log(Number.isNaN(NaN));        // true
console.log(Number.isNaN(Number.NaN)); // true
console.log(Number.isNaN(0 / 0));      // true
 
console.log(Number.isNaN("NaN"));      // false
console.log(Number.isNaN(undefined));  // false
console.log(Number.isNaN({}));         // false
console.log(Number.isNaN("blabla"));   // false

Number.isNaN() provides a more reliable way to check for NaN values, especially in cases where type coercion might lead to unexpected results with the global isNaN() function. In practice, when dealing with numerical operations or user inputs that should be numbers, it’s often necessary to check for NaN to handle errors or unexpected inputs gracefully. For example:

function divide(a, b) {
  let result = a / b;
  if (Number.isNaN(result)) {
    return "Error: Division resulted in NaN";
  }
  return result;
}
 
console.log(divide(10, 2));  // 5
console.log(divide(10, 0));  // Infinity
console.log(divide(0, 0));   // "Error: Division resulted in NaN"

In this example, we’re using Number.isNaN() to catch cases where the division operation results in NaN, allowing us to handle this scenario appropriately. Understanding NaN and how to properly check for it is crucial for writing robust JavaScript code, especially when dealing with mathematical operations or parsing user inputs.