← Назад к вопросам

Что будет при сравнении с NaN?

1.0 Junior🔥 172 комментариев
#JavaScript Core

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Сравнение с NaN в JavaScript

При сравнении с NaN (Not-a-Number) в JavaScript возникает особое поведение, которое часто становится источником ошибок. NaN — это специальное значение, представляющее результат некорректной математической операции, и оно обладает уникальными характеристиками сравнения.

Основное правило сравнения

Ключевое правило: NaN не равно ничему, включая самого себя. Это единственное значение в JavaScript, которое не равно самому себе.

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

Почему так происходит?

Такое поведение обусловлено стандартом IEEE 754 для чисел с плавающей запятой, который определяет NaN как неупорядоченное значение. Поскольку NaN представляет неопределённый или невычислимый результат, логично, что он не может считаться равным другому неопределённому значению.

Практические последствия

1. Невозможность обнаружения через прямое сравнение

const value = Math.sqrt(-1); // NaN

// Неправильный подход:
if (value === NaN) { // Всегда false
    console.log('Это NaN!'); // Никогда не выполнится
}

// Правильный подход:
if (Number.isNaN(value)) {
    console.log('Это точно NaN!'); // Выполнится
}

2. Особенности с операторами сравнения

console.log(NaN > 5);   // false
console.log(NaN < 5);   // false
console.log(NaN >= 5);  // false
console.log(NaN <= 5);  // false
console.log(NaN > NaN); // false
console.log(NaN < NaN); // false

3. Влияние на сортировку массивов

const arr = [5, 2, NaN, 8, NaN, 1];
arr.sort();
console.log(arr); // [1, 2, 5, 8, NaN, NaN] - NaN всегда в конце

Методы для проверки на NaN

Number.isNaN() (рекомендуется)

Строгая проверка: возвращает true только если значение точно является NaN.

console.log(Number.isNaN(NaN));      // true
console.log(Number.isNaN('текст'));  // false
console.log(Number.isNaN(undefined)); // false

isNaN() (глобальная функция)

Более широкий подход: пытается преобразовать значение к числу перед проверкой.

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

Object.is()

Метод для строгого сравнения, который корректно обрабатывает NaN.

console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(0, -0));    // false (в отличие от ===)

Распространённые ошибки и лучшие практики

  1. Никогда не полагайтесь на == или === для проверки NaN

    // ❌ Плохо:
    if (x === NaN) { ... }
    
    // ✅ Правильно:
    if (Number.isNaN(x)) { ... }
    
  2. Проверяйте входные данные математических операций

    function safeDivision(a, b) {
        if (Number.isNaN(a) || Number.isNaN(b)) {
            throw new Error('Invalid input: NaN detected');
        }
        return a / b;
    }
    
  3. Используйте Number.isNaN() вместо глобального isNaN() Глобальная функция isNaN() имеет неочевидное поведение из-за приведения типов.

  4. Обрабатывайте NaN при работе с массивами

    const data = [1, 2, NaN, 4, 5];
    const cleanData = data.filter(v => !Number.isNaN(v));
    console.log(cleanData); // [1, 2, 4, 5]
    

Особые случаи

// NaN в объектах и массивах
const obj = { value: NaN };
console.log(obj.value === obj.value); // false!

// NaN в Set и Map
const set = new Set();
set.add(NaN);
set.add(NaN);
console.log(set.size); // 1 - NaN считается одинаковым

Вывод

Сравнение с NaN — это особый случай в JavaScript, требующий специальных методов проверки. Понимание этого поведения критически важно для написания надёжного кода, особенно при обработке пользовательского ввода, математических вычислений и валидации данных. Всегда используйте Number.isNaN() для точной проверки и помните, что NaN распространяется через большинство математических операций, что может привести к незаметным ошибкам в цепочках вычислений.