Что такое NaN, какой у него тип и как его проверить?

👨‍💻 Frontend Developer 🟠 Может встретиться 🎚️ Легкий
#JavaScript #Типы данных #База JS

Краткий ответ

NaN (Not-a-Number) — это специальное числовое значение в JavaScript, которое представляет результат некорректной или неопределенной математической операции. Несмотря на название «не число», его тип данных — number. Самый надежный способ проверить значение на NaN — это метод Number.isNaN(), поскольку NaN не равен ничему, включая самого себя (NaN === NaN вернет false).


Что такое NaN

NaN — это глобальное свойство, представляющее значение «не число». Это одно из особых значений числового типа number в стандарте IEEE 754, которое используется для представления результатов, которые не могут быть выражены как действительные числа.

Тип данных NaN

Несмотря на свое название, NaN технически является числом.

console.log(typeof NaN); // "number"

Особенности:

  • NaN принадлежит к типу number.
  • ✅ Это позволяет числовым операциям возвращать число, даже если результат не является реальным числом, избегая ошибок во время выполнения.

Как получить NaN

NaN возвращается, когда математическая операция не может вернуть осмысленное числовое значение.

1. Некорректные математические операции

// Деление нуля на ноль
console.log(0 / 0); // NaN
 
// Извлечение корня из отрицательного числа
console.log(Math.sqrt(-1)); // NaN
 
// Умножение бесконечности на ноль
console.log(Infinity * 0); // NaN

2. Преобразование нечисловых строк

Когда JavaScript пытается преобразовать строку, не содержащую число, в число, результат будет NaN.

// Явное преобразование
console.log(parseInt('привет')); // NaN
console.log(Number('abc')); // NaN
 
// Неявное преобразование при математических операциях
console.log('строка' - 10); // NaN
console.log('10a' * 5); // NaN

Особенности:

  • NaN «заразителен»: любая операция с NaN вернет NaN.
  • console.log(1 + NaN); // NaN
  • console.log('текст' + NaN); // "текстNaN" (здесь происходит конкатенация строк)

Проверка на NaN

Проверка на NaN имеет свои особенности, так как NaN — единственное значение в JavaScript, которое не равно самому себе.

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

1. Number.isNaN() (рекомендуемый способ)

Это самый надежный и предпочтительный метод. Он проверяет, является ли переданное значение NaN, и не пытается его преобразовать.

console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(123)); // false
console.log(Number.isNaN('abc')); // false (не преобразует строку в число)
console.log(Number.isNaN(undefined)); // false

Особенности:

  • ✅ Не выполняет приведение типов.
  • ✅ Точно определяет только NaN.
  • ✅ Является частью стандарта ES6.

2. Глобальная функция isNaN()

Этот метод менее надежен, так как он сначала пытается преобразовать аргумент в число.

console.log(isNaN(NaN)); // true
console.log(isNaN('abc')); // true, потому что Number('abc') -> NaN
console.log(isNaN(undefined)); // true, потому что Number(undefined) -> NaN
console.log(isNaN({})); // true, потому что Number({}) -> NaN

Особенности:

  • ❌ Может давать ложноположительные результаты.
  • ❌ Считается устаревшим и ненадежным для точной проверки.

3. Проверка на неравенство самому себе

Это «хакерский», но рабочий способ, основанный на уникальном свойстве NaN.

function isValueNaN(value) {
  return value !== value;
}
 
console.log(isValueNaN(NaN)); // true
console.log(isValueNaN(123)); // false
console.log(isValueNaN('abc')); // false

Особенности:

  • ✅ Работает надежно и быстро.
  • ✅ Не требует специальных функций.
  • ❌ Менее читаем и очевиден, чем Number.isNaN().

Задачи для практики

Задача 1

// Что выведет этот код в консоль?
console.log(typeof NaN);
console.log(NaN === NaN);
console.log(Number.isNaN('hello'));
console.log(isNaN('hello'));
Ответ **Объяснение:** 1. Тип `NaN` — `number`. 2. `NaN` не равен самому себе. 3. `Number.isNaN()` не преобразует типы, поэтому строка — это не `NaN`. 4. `isNaN()` преобразует строку 'hello' в `NaN` и возвращает `true`.

Задача 2

// Напишите функцию, которая принимает массив и возвращает
// только числовые значения, исключая NaN.
 
function filterNumbers(arr) {
  // Ваш код
}
 
const data = [1, 'a', 2, NaN, 3, undefined, 4, null, '5'];
console.log(filterNumbers(data)); // [1, 2, 3, 4]
Ответ
function filterNumbers(arr) {
  return arr.filter(item => typeof item === 'number' && !Number.isNaN(item));
}

Объяснение: Мы фильтруем массив, оставляя только элементы с типом number, и дополнительно убеждаемся, что это не NaN с помощью Number.isNaN().