NaN (Not a Number) - спеціальне значення типу number, яке означає результат невизначеної чи неможливої числової операції:
typeof NaN; // 'number'
Number('abc'); // NaN
0 / 0; // NaN
Math.sqrt(-1); // NaN
undefined + 1; // NaN
NaN не дорівнює нічому, навіть собі. Так визначено стандартом IEEE 754 для чисел з рухомою комою:
NaN === NaN; // false
NaN == NaN; // false
const x = NaN;
x !== x; // true - єдине значення з такою властивістю
Тому if (value === NaN) ніколи не спрацює.
Як перевіряти правильно:
Number.isNaN(value); // true лише для справжнього NaN
Object.is(value, NaN); // теж true
Не плутати з глобальною isNaN(). Вона спершу перетворює аргумент на число, тож відповідає на інше питання - «чи стане це NaN після перетворення»:
isNaN('abc'); // true - 'abc' перетворився на NaN
Number.isNaN('abc'); // false - це рядок, а не NaN
isNaN(undefined); // true
isNaN(''); // false - '' перетворюється на 0
Для перевірки «чи є це коректним числом» найзручніше Number.isFinite(value): false для NaN, Infinity і будь-яких нечислових типів.
NaN «заражає» обчислення: будь-яка арифметика з NaN дає NaN. Одне некоректне значення в масиві перетворить суму на NaN:
[10, 20, Number('')].reduce((a, b) => a + b); // 30 ('' дає 0)
[10, 20, Number('x')].reduce((a, b) => a + b); // NaN
Звідси правило: перевіряти дані на вході (при парсингу форми чи відповіді API), а не шукати, де з'явився NaN, у кінці розрахунку.
Різні методи по-різному бачать NaN:
[NaN].includes(NaN)→true(алгоритм SameValueZero);[NaN].indexOf(NaN)→-1(строга рівність);new Set([NaN, NaN]).size→1;JSON.stringify(NaN)→'null'-NaNтихо перетворюється наnullпри відправці на сервер.