Что такое NaN и в каких случаях он возникает
Что проверяют
Знаете ли вы приведение типов в JavaScript и умеете ли правильно проверять значение. Вопрос часто начинается с typeof NaN и NaN === NaN, а заканчивается разницей между isNaN и Number.isNaN.
Как отвечать
NaN это значение типа number из стандарта IEEE 754, результат операции, у которой нет числового ответа. typeof NaN возвращает "number".
Когда появляется:
- неопределённая арифметика:
0 / 0,Infinity - Infinity,Math.sqrt(-1); - неудачное приведение:
Number("abc"),parseInt("px10"),+{},undefined + 1. При этомNumber(""),Number(null)и+[]дают0, это тоже любят спрашивать; - распространение: любая арифметика с NaN даёт NaN, поэтому одно пустое поле формы превращает всю сумму корзины в NaN;
- невалидная дата:
new Date("foo").getTime()возвращает NaN.
Проверка. NaN единственное значение, не равное самому себе, поэтому === не подходит. Правильно использовать Number.isNaN(x): он возвращает true только для настоящего NaN. Глобальный isNaN сначала приводит аргумент к числу, и isNaN("abc") даёт true. Другие варианты: Object.is(x, NaN) и Number.isFinite(x), если заодно нужно отсечь Infinity.
Полезно знать поведение в коллекциях: [NaN].includes(NaN) вернёт true, а [NaN].indexOf(NaN) вернёт -1, потому что includes сравнивает по SameValueZero. Set и Map тоже считают NaN равным себе. JSON.stringify(NaN) даёт строку "null", и на бэкенд уходит не то, что ожидали.
Где спотыкаются
Говорят, что деление на ноль даёт NaN. 10 / 0 это Infinity, NaN получается только из 0 / 0.
Проверяют через глобальный isNaN и получают true для строки или undefined, хотя там не NaN.
Ставят запасное значение через ??. NaN не null и не undefined, поэтому x ?? 0 его пропустит. Нужен Number.isNaN или ||, если ноль как валидное значение не важен.