Suggest an editImprove this articleRefine the answer for “What is nan in JavaScript?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**NaN** (Not-a-Number) is a numeric value in JavaScript that signals an invalid math result, like `0 / 0` or parsing a non-numeric string. ```javascript NaN === NaN; // false typeof NaN; // "number" Number.isNaN(NaN); // true ``` **Key:** use `Number.isNaN()` to check, not `=== NaN` and not global `isNaN()`.Shown above the full answer for quick recall.Answer (EN)Image**NaN** is a special numeric value in JavaScript that signals an invalid math result, like dividing zero by zero or parsing a non-numeric string. ## Theory ### TL;DR - NaN stands for "Not-a-Number," yet `typeof NaN === "number"` — it lives inside the number type - Think of it as a poisoned pill: one NaN in a calculation contaminates every result that follows - `NaN !== NaN` is always `false`. Not a bug, that is the spec - `Number.isNaN()` is the correct check. Global `isNaN()` coerces strings first and gives wrong answers ### Quick example ```javascript console.log(0 / 0); // NaN console.log(typeof NaN); // "number" console.log(NaN === NaN); // false console.log(Number.isNaN(NaN)); // true const result = "abc" * 5; console.log(result + 10); // NaN (propagates) ``` NaN spreads. Any arithmetic on NaN gives back NaN. That one bad input can ruin a whole chain of calculations with no error thrown. ### Why NaN !== NaN The IEEE 754 floating-point standard defines NaN as "unordered." Two invalid results can come from completely different broken operations: `0/0` and `Math.sqrt(-1)` are both NaN, but they describe different kinds of invalid math. So the standard says equality with NaN always returns `false`. This forces you to detect it explicitly rather than accidentally trusting it. V8 stores NaN as the bit pattern `0x7FF8000000000000`. The `===` operator compares bit patterns, and any comparison involving NaN returns `false` by spec. No exceptions. ### When to use Number.isNaN() - Input parsing: check `Number.isNaN()` before any calculation on user input - API responses: replace NaN with `null` before sending JSON (`JSON.stringify` converts NaN to `null` anyway, which can break client math without throwing) - Array reductions: filter out NaN before calling `.reduce()` - Anywhere you use global `isNaN()`: replace it with `Number.isNaN()` ### How JavaScript creates NaN Invalid numeric operations produce NaN: dividing zero by zero, taking the square root of a negative number, parsing a non-numeric string with `Number()` or `parseInt()`. After that, any arithmetic involving NaN automatically produces NaN. The infection is automatic. ### Common mistakes **Comparing with ===** ```javascript if (result === NaN) { /* this never runs */ } ``` NaN never equals anything, including itself. Fix: `Number.isNaN(result)`. **Using global isNaN() on strings** ```javascript isNaN("hello"); // true (coerced to NaN) isNaN("123abc"); // true (coerced to NaN) isNaN("123"); // false (coerced to 123) ``` Global `isNaN()` converts the argument first. It cannot distinguish "this is actually NaN" from "this string does not parse as a number." Use `Number.isNaN(Number(value))` when you need both checks. **NaN in JSON** ```javascript JSON.stringify({ score: NaN }); // {"score":null} ``` JSON has no NaN literal. Serialization converts it to `null`. If your client reads that `null` and tries to do math, results will be wrong with no error. Sanitize before stringify. **NaN poisoning Math.min / Math.max** ```javascript Math.min(1, NaN, 3); // NaN ``` One NaN poisons the whole aggregate. Filter the array first. ### Real-world usage - React / Formik: `Number.isNaN()` in numeric field validators before form submission - Express: parse `req.query.age` with `parseInt()`, check for NaN before database queries - D3.js: filter NaN from chart data arrays before computing scales - Lodash: `_.isNaN()` as a convenience wrapper in utility functions ### Follow-up questions **Q:** Why does `typeof NaN === "number"` if NaN is not a valid number? **A:** JavaScript's type system follows IEEE 754. NaN is part of the floating-point number space, just an invalid state within it. The type label is technically correct. **Q:** What is the difference between `isNaN()` and `Number.isNaN()`? **A:** Global `isNaN()` coerces the argument, so `isNaN("foo")` returns `true`. `Number.isNaN()` skips coercion and only returns `true` for the actual NaN value, so `Number.isNaN("foo")` returns `false`. **Q:** How do you handle NaN in an array reduce? **A:** Filter before reducing: `.filter(v => !Number.isNaN(v))`. Or guard inside the callback with a fallback value. **Q:** What does JSON.stringify do with NaN? **A:** It converts NaN to `null`. JSON has no NaN representation. Always sanitize data before serialization. **Q:** (Senior) V8 stores NaN as `0x7FF8000000000000`. Why does `+NaN === NaN` still return `false`? **A:** The unary `+` returns the same bit pattern. But IEEE 754 specifies that any comparison involving NaN must return `false` regardless. This is intentional so invalid values cannot accidentally pass equality checks. ## Examples ### Parsing user input ```javascript const userAge = "25a"; const age = parseInt(userAge, 10); // NaN if (Number.isNaN(age)) { console.log("Invalid age"); // runs } else { console.log(`Age in 5 years: ${age + 5}`); } // Output: "Invalid age" ``` `parseInt` stops at the first non-numeric character and returns NaN. Check before you calculate, not after. ### Fixing NaN in array reduce ```javascript const prices = ["$10", "20", "abc"]; // Without fix: NaN poisons the sum const broken = prices.reduce((sum, p) => sum + Number(p), 0); console.log(broken); // NaN // With fix: filter invalid values first const total = prices .map(p => Number(p.replace("$", ""))) .filter(v => !Number.isNaN(v)) .reduce((sum, v) => sum + v, 0); console.log(total); // 30 ``` I have seen this exact pattern break production dashboards where one bad API value turned an entire summary widget to NaN. The fix is one line.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.