Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое none, null, undefined и NaN в JavaScript
В JavaScript нет типа данных none (как в Python), но есть несколько похожих концептов: null, undefined и NaN. Это источник путаницы для новичков, поэтому разберёмся детально.
undefined
undefined — это значение, которое JavaScript присваивает автоматически в случаях, когда нет конкретного значения.
Когда появляется undefined:
// 1. Переменная объявлена, но не инициализирована
let x;
console.log(x); // undefined
// 2. Функция не вернула значение
function noReturn() {
const a = 5;
}
console.log(noReturn()); // undefined
// 3. Параметр функции не передан
function greet(name) {
console.log(name); // undefined если не передали
}
greet();
// 4. Свойство объекта не существует
const obj = { name: 'John' };
console.log(obj.age); // undefined
// 5. Функция вернула return без значения
function empty() {
return; // это то же самое, что return undefined
}
console.log(empty()); // undefined
undefined — это тип данных "undefined":
console.log(typeof undefined); // "undefined"
null
null — это намеренное отсутствие значения. Это значение вы устанавливаете явно.
// Явно устанавливаем null
let user = null; // "нет пользователя"
let data = null; // "данные ещё не загружены"
function findUser(id) {
if (id === 0) {
return null; // явно указываем: пользователя не найдено
}
return { id, name: 'John' };
}
Особенность: typeof null возвращает "object" (историческая ошибка в JavaScript):
console.log(typeof null); // "object" (это баг!)
console.log(null === null); // true
undefined vs null
// undefined == null (слабое равенство)
console.log(undefined == null); // true ✓
// undefined !== null (строгое равенство)
console.log(undefined === null); // false ✗
// Проверка на оба
if (value == null) {
// value либо null, либо undefined
}
if (value === undefined || value === null) {
// то же самое, но с строгим равенством
}
NaN (Not a Number)
NaN — это специальное значение, которое означает "результат не является числом". Парадокс: typeof NaN возвращает "number"!
console.log(typeof NaN); // "number" (ещё один баг!)
Когда появляется NaN:
// 1. Недопустимое математическое действие
console.log(0 / 0); // NaN
console.log(Math.sqrt(-1)); // NaN
// 2. Неудачное преобразование строки в число
console.log(parseInt('hello')); // NaN
console.log(Number('not a number')); // NaN
// 3. Операции с NaN
console.log(NaN + 5); // NaN
console.log(NaN === NaN); // false (уникальное свойство NaN!)
Проверка на NaN:
const value = parseInt('hello');
// ❌ Неправильно: NaN !== NaN
if (value === NaN) {
console.log('Это NaN');
} // Это не работает!
// ✅ Правильно: используй isNaN()
if (isNaN(value)) {
console.log('Это NaN'); // Работает!
}
// ✅ Лучше: используй Number.isNaN()
if (Number.isNaN(value)) {
console.log('Это точно NaN');
}
// Разница:
console.log(isNaN('hello')); // true (преобразует строку!)
console.log(Number.isNaN('hello')); // false (только реальные NaN)
Таблица сравнения
┌─────────┬──────────┬───────────────┬─────────────────────┐
│ Значение│ typeof │ Тип │ Когда появляется │
├─────────┼──────────┼───────────────┼─────────────────────┤
│undefined│undefined │ undefined │ Автоматически │
│ null │ object │ (историческая │ Явно установлено │
│ │ │ ошибка) │ │
│ NaN │ number │ (историческая │ Ошибка в расчётах │
│ │ │ ошибка) │ │
└─────────┴──────────┴───────────────┴─────────────────────┘
Falsy значения в JavaScript
undefined, null и NaN относятся к falsy значениям (при приведении к boolean они становятся false):
const falsy = [undefined, null, NaN, false, 0, '', 0n];
falsy.forEach(value => {
if (!value) {
console.log(value, '→ falsy');
}
});
// В условиях
if (!user) { // true если user null, undefined, NaN, false, 0, или ''
console.log('Пользователя нет');
}
Практические примеры
API ответ с undefined:
async function loadUser(id) {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
return undefined; // явно: данные не загружены
}
return response.json();
}
const user = await loadUser(1);
if (user === undefined) {
console.log('Ошибка загрузки');
}
Проверка свойства:
const config = { timeout: 5000 };
// undefined: свойство не существует
if (config.retries === undefined) {
config.retries = 3; // устанавливаем значение по умолчанию
}
// Лучший способ: optional chaining и nullish coalescing
const retries = config.retries ?? 3; // использует 3 если null/undefined
Optional chaining (?.):
const user = { name: 'John' };
// ❌ Ошибка если user.address null
const city = user.address.city; // TypeError!
// ✅ Вернёт undefined если address null/undefined
const city = user.address?.city; // undefined
// Цепочка
const zip = user?.address?.city?.zip ?? 'unknown';
Nullish coalescing operator (??):
// null или undefined: используй значение справа
const value = null ?? 'default'; // 'default'
const value = undefined ?? 'default'; // 'default'
// Другие falsy: НЕ заменяются
const value = 0 ?? 'default'; // 0 (не меняется!)
const value = '' ?? 'default'; // '' (не меняется!)
const value = false ?? 'default'; // false (не меняется!)
// Отличие от || (которое заменяет все falsy)
const value = 0 || 'default'; // 'default' (меняется)
Самые частые ошибки
// ❌ Ошибка 1: Проверка NaN
if (value === NaN) { } // Не работает!
if (Number.isNaN(value)) { } // ✅ Правильно
// ❌ Ошибка 2: Смешивание undefined и null
if (value === undefined) { } // Не ловит null
if (value == null) { } // ✅ Правильно (ловит оба)
// ❌ Ошибка 3: Не использовать optional chaining
const city = data.user.address.city; // Error!
const city = data?.user?.address?.city; // ✅ Правильно
// ❌ Ошибка 4: Использовать || вместо ??
const count = settings.count || 10; // Неправильно если count = 0
const count = settings.count ?? 10; // ✅ Правильно
Итоги
undefined— автоматическое отсутствие значенияnull— явное указание на отсутствие значенияNaN— результат невалидной математической операции- Используй
==для проверки на оба (null и undefined) - Используй
Number.isNaN()для проверки на NaN - Модерный JavaScript: optional chaining (?.) и nullish coalescing (??)
- Всегда проверяй наличие значений перед использованием свойств