Комментарии (2)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Когда используется null в JavaScript
Определение
null — это специальное значение в JavaScript, которое представляет намеренное отсутствие значения. Это значение, которое явно устанавливает разработчик.
typeof null; // "object" — да, это ошибка в JavaScript!
const value = null; // Явно устанавливаю "нет значения"
null vs undefined
Это две разные вещи, и их важно различать:
// undefined — переменная не инициализирована
let x;
console.log(x); // undefined
function test(param) {
console.log(param); // undefined если не передали
}
test(); // undefined
// null — отсутствие значения по конструкции
const user = { name: null }; // Явно сказали "нет имени"
const result = null; // Функция вернула "ничего"
Таблица различий
| Характеристика | null | undefined |
|---|---|---|
| Тип | object (ошибка языка) | undefined |
| Причина | Намеренное отсутствие | Неинициализированная переменная |
| Сравнение | null == undefined | true |
| null === undefined | false | |
| typeof | "object" | "undefined" |
null == undefined; // true (нестрогое сравнение)
null === undefined; // false (строгое сравнение)
Object.keys({ a: null, b: undefined });
// ["a", "b"] — оба ключа есть
JSON.stringify({ a: null, b: undefined });
// {"a":null} — undefined исключается
Когда использовать null
1. Опциональные значения в объектах
const user = {
id: 123,
name: "Alice",
middleName: null, // У человека может не быть отчества
email: "alice@example.com",
phone: null // Не захотел указывать телефон
};
// Вместо:
const user2 = {
id: 123,
name: "Alice",
email: "alice@example.com"
// middleName и phone отсутствуют
};
// null явно говорит: "Мы знаем про это поле, но значения нет"
2. Функции, которые могут ничего не вернуть
// Ищу пользователя по ID
function findUser(id) {
const user = db.users.find(u => u.id === id);
return user || null; // Явно возвращаю null если не найден
}
// Использование
const user = findUser(123);
if (user === null) {
console.log('User not found');
} else {
console.log(user.name);
}
// Вместо undefined (который может быть случайным)
function badFindUser(id) {
return db.users.find(u => u.id === id); // Может вернуть undefined
}
3. БД и API responses
// В SQL NULL и в JSON null — это ноль значений
// SQL
SELECT id, name, phone FROM users;
-- id: 1, name: "Alice", phone: NULL (в БД)
// JSON response
{
"id": 1,
"name": "Alice",
"phone": null // null в JSON
}
// TypeScript модель
interface User {
id: number;
name: string;
phone: string | null; // Может быть null
}
4. Результат JSON.parse при ошибке
// Парсим JSON
const data = JSON.parse('{"name": null}');
console.log(data.name); // null
// Если значение в JSON null, то в JS получаем null
const empty = JSON.parse('null');
console.log(empty); // null (само значение)
// Но если JSON невалидный — ошибка
JSON.parse('{invalid}'); // SyntaxError
5. Явное присвоение по умолчанию
function initializeUser(name, avatar = null) {
return {
name,
avatar, // Если не передали — будет null
createdAt: new Date()
};
}
initializeUser('Alice'); // { name: 'Alice', avatar: null, ... }
initializeUser('Bob', 'avatar.jpg'); // { name: 'Bob', avatar: 'avatar.jpg', ... }
Когда НЕ использовать null
❌ Не используй null для ошибок
// ❌ Плохо
function divide(a, b) {
if (b === 0) return null; // Как отличить от "результат null"?
return a / b;
}
const result = divide(10, 0);
if (result === null) { // Это ошибка или результат?
console.log('Error');
}
// ✅ Хорошо
function divide(a, b) {
if (b === 0) throw new Error('Division by zero');
return a / b;
}
try {
const result = divide(10, 0);
} catch (error) {
console.log('Error:', error.message);
}
❌ Не используй null вместо undefined
// ❌ Плохо
function process(data = null) {
if (data === null) { /* ... */ }
}
// ✅ Хорошо
function process(data = undefined) {
if (data === undefined) { /* ... */ }
}
// или еще лучше
function process(data?) {
if (!data) { /* ... */ }
}
❌ Не пусть null распространяться в коде
// ❌ Плохо
const user = getUser(); // может быть null
const name = user.name; // Crash если user === null!
// ✅ Хорошо (опциональный chaining)
const name = user?.name; // undefined если user === null
// ✅ Или проверка
if (user !== null) {
const name = user.name;
}
Правильная работа с null
Проверки null
const value = null;
// Проверка на null
if (value === null) { /* ... */ }
if (value !== null) { /* ... */ }
// Проверка на null или undefined
if (value == null) { /* ... */ } // == работает для обоих
if (value != null) { /* ... */ }
// Опциональный chaining
const name = value?.name; // undefined если value === null
const method = value?.toString?.(); // undefined если нет метода
// Nullish coalescing
const result = value ?? 'default'; // Используй 'default' если value === null
Практические примеры
// Пример 1: Optional chaining с методами
const user = await getUser();
const email = user?.email?.toLowerCase(); // undefined если user = null
// Пример 2: Nullish coalescing
const age = user?.age ?? 18; // 18 если user.age = null или undefined
// Пример 3: Type guards
function processUser(user: User | null) {
if (user === null) {
console.log('No user');
return;
}
// Теперь TypeScript знает, что user не null
console.log(user.name);
}
null в TypeScript
// Strict mode в TypeScript (strictNullChecks: true)
interface User {
id: number;
name: string;
phone: string | null; // Может быть null
email: string; // НЕ может быть null
}
const user: User = {
id: 1,
name: "Alice",
phone: null, // ✅ OK
email: "alice@example.com"
};
const user2: User = {
id: 2,
name: "Bob",
phone: null,
email: null // ❌ Error: Type 'null' is not assignable to type 'string'
};
// Обработка null
if (user.phone !== null) {
console.log(user.phone.length); // ✅ OK, TypeScript знает phone не null
}
null в API и БД
REST API Response
// Пример ответа с null значениями
{
"id": 1,
"username": "alice",
"email": "alice@example.com",
"phone": null, // Нет телефона
"avatar": null, // Нет аватара
"middleName": null, // Нет отчества
"verified": false
}
PostgreSQL
-- NULL в SQL и null в JSON
SELECT id, username, email, phone FROM users;
-- Результат:
-- id | username | email | phone
-- 1 | alice | alice@example.com | NULL
-- 2 | bob | bob@example.com | +1234567890
-- JSON ответ будет
-- [{ id: 1, phone: null }, { id: 2, phone: "+1234567890" }]
Лучшие практики
1. Явно документируй null
/**
* Получить пользователя по ID
* @param id User ID
* @returns User object or null if not found
*/
function getUser(id: number): User | null {
return db.users.findOne({ id }) || null;
}
2. Используй опциональный chaining
// ✅ Современный способ
const name = user?.profile?.name;
const method = obj?.method?.();
// ❌ Старый способ
const name = user && user.profile && user.profile.name;
3. Используй nullish coalescing для значений по умолчанию
// ✅ Правильно (только если value === null или undefined)
const result = value ?? 'default';
// ❌ Неправильно (если value = 0, будет 'default'!)
const result = value || 'default';
4. Обрабатывай null в начале функции (guard clauses)
// ✅ Хорошо: guard clause
function processUser(user: User | null) {
if (user === null) return;
// Дальше пишем с уверенностью, что user не null
console.log(user.name);
}
// ❌ Плохо: вложенные if
function processUser(user: User | null) {
if (user !== null) {
if (user.active) {
if (user.verified) {
// Много уровней вложенности
}
}
}
}
Вывод
Используй null когда:
- Явно нужно обозначить отсутствие значения
- Поле в объекте может не иметь значения
- Функция может вернуть ничего
- Работаешь с БД или API (где есть NULL)
Не используй null когда:
- Нужно обозначить ошибку (выброси исключение)
- Это случайное отсутствие значения (используй undefined)
- Функция всегда должна вернуть значение
В современном JavaScript:
- Используй
?.(optional chaining) для безопасного доступа - Используй
??(nullish coalescing) для значений по умолчанию - В TypeScript включи
strictNullChecksдля type-safety - Документируй, какие поля могут быть null