HuntExams Academy logo
JavaScriptBeginner#numbers

What is NaN and how do you check for it?

Answer

NaN is the numeric result of an invalid computation and is the only value not equal to itself. Use Number.isNaN, which does not coerce, rather than the legacy global isNaN.

Example

0/0;               // NaN
NaN === NaN;       // false
Number.isNaN('a'); // false
isNaN('a');        // true (coerces)

Detailed explanation

NaN stands for “Not-a-Number”, but it is a special value of JavaScript’s Number type: typeof NaN returns 'number'. It represents an undefined or unrepresentable numeric result, or a failed numeric conversion. For example, 0 / 0, Math.sqrt(-1), and Number('a') produce NaN. Parsing can also produce it: parseInt('hello', 10) returns NaN because no valid starting integer can be read. NaN is a returned value, not an exception, so these operations do not automatically enter a catch block.

Under the hood, JavaScript’s Number type uses IEEE 754 double-precision floating-point representation, which includes special values such as NaN and Infinity. NaN has an unusual equality rule: it is unequal to every value, including itself. Therefore, NaN === NaN and NaN == NaN both return false. This is why checking value === NaN never works. The expression value !== value detects NaN, but it is less readable than a named check. Most arithmetic involving NaN also produces NaN, allowing one invalid value to spread through later calculations. Not every problematic-looking calculation produces NaN: 1 / 0 produces Infinity.

The preferred check is Number.isNaN(value). It returns true only when the supplied value is actually the numeric NaN value, without converting its input. Consequently, Number.isNaN(NaN) is true, while Number.isNaN('a'), Number.isNaN(undefined), and Number.isNaN('123') are false. The older global isNaN(value) first converts its argument to a number and then checks the result. Thus, isNaN('a') and isNaN(undefined) are true, while isNaN('123') and isNaN('') are false because those strings convert to 123 and 0 respectively.

In an interview, distinguish detecting NaN from validating input. For form data, explicitly convert with Number(input), then check the converted result; reject empty input separately if your requirements demand it. If you need a finite numeric value, use Number.isFinite on the converted number to reject both NaN and infinities. Interviewers generally look for correct equality behaviour, awareness of coercion, and a check that matches the actual validation requirement.

Key points to remember

  • NaN is a special Number value; typeof NaN is 'number'.
  • Invalid numeric operations and failed numeric conversions can produce NaN.
  • NaN is the only JavaScript value unequal to itself under ===.
  • Number.isNaN checks for actual NaN without coercion; global isNaN converts first.
  • Number.isFinite rejects NaN, Infinity, and -Infinity without coercing input.

Common mistakes candidates make

  • Using value === NaN, which always returns false.
  • Treating isNaN('a') as proof that the string itself is NaN, instead of recognising the conversion.
  • Assuming !Number.isNaN(value) proves that value is a valid number; strings and undefined also pass that test.

Likely follow-up questions

How would you validate a number entered in a text field?

Reject blank input if it is not allowed, then convert the string using Number(input). Use Number.isFinite on the result when only finite numbers are valid, and apply any required range checks.

Does Object.is handle NaN differently from ===?

Yes, Object.is(NaN, NaN) returns true, while NaN === NaN returns false. Object.is also distinguishes +0 from -0, whereas === treats them as equal.

Can you find NaN inside an array?

Array.prototype.includes can find it: [NaN].includes(NaN) returns true because includes uses SameValueZero comparison. By contrast, [NaN].indexOf(NaN) returns -1 because indexOf uses strict equality.

Interview tip: Define NaN, demonstrate its unusual equality rule, then contrast Number.isNaN('a') with isNaN('a') to explain coercion.

Related Interview Questions

1
JavaScriptIntermediate#numbers

Why is 0.1 + 0.2 !== 0.3?

Open
2
JavaScriptIntermediate#dom#events

What is event delegation useful for in dynamic lists?

Open
3
JavaScriptIntermediate#browser#performance

What is the difference between defer and async on a script tag?

Open