JavaScriptJuniorTechnical
Объясните разницу между null и undefined.
undefined — JS автоматически ставит, когда значение не задано; null — разработчик явно указывает «пусто». Строгое сравнение === различает их, нестрогое == считает равными.
null и undefined в JavaScript
Оба значения обозначают «отсутствие данных», но имеют разный смысл и разное происхождение.
undefined — значение не задано
undefined — примитив, который JavaScript присваивает автоматически в следующих случаях:
- Переменная объявлена, но не инициализирована:
let x;→x === undefined - Обращение к несуществующему свойству объекта:
obj.missing === undefined - Функция не возвращает значение явно:
function f() {} → f() === undefined - Параметр функции не передан:
function f(a) { return a; } f() === undefined - Чтение за пределами массива:
[1,2][5] === undefined
null — намеренное отсутствие
null — примитив, который разработчик присваивает явно, чтобы обозначить «пустое» или «сброшенное» значение:
- Сброс ссылки на объект:
let user = getUser(); user = null; - Возврат «ничего» из функции по смыслу:
document.getElementById('missing') === null - Инициализация поля, которое заполнят позже:
let token = null;
Ключевые различия
console.log(typeof undefined); // "undefined"
console.log(typeof null); // "object" — историческая ошибка JS
console.log(null == undefined); // true — нестрогое сравнение
console.log(null === undefined); // false — строгое сравнение
console.log(null + 1); // 1 — null приводится к 0
console.log(undefined + 1); // NaN — undefined приводится к NaN
// JSON: undefined игнорируется, null сохраняется
JSON.stringify({ a: undefined, b: null }); // '{"b":null}'
Практические паттерны
// Nullish coalescing — реагирует только на null/undefined
const name = user.name ?? 'Аноним';
// Optional chaining — безопасный доступ
const city = user?.address?.city;
// Проверка «есть ли значение»
function greet(name) {
if (name == null) { // поймает и null, и undefined
throw new Error('Имя обязательно');
}
return `Привет, ${name}`;
}
// Различие в деструктуризации
const { a = 'default' } = { a: undefined }; // a === 'default'
const { b = 'default' } = { b: null }; // b === null (не default!)
TypeScript: NonNullable
type MaybeUser = User | null | undefined;
function processUser(user: NonNullable<MaybeUser>) {
// user гарантированно не null и не undefined
console.log(user.id);
}
// Утверждение ненулевого значения
const el = document.getElementById('app')!; // оператор !
Подводные камни
- typeof null === "object" — баг с 1995 года, не исправлен из-за обратной совместимости; никогда не используйте typeof для проверки null, используйте
=== null. - Дефолтные параметры не срабатывают для null —
function f(x = 5) {}:f(null)дастx = null, а не 5; срабатывает только для undefined. - JSON.stringify удаляет undefined — поля со значением undefined исчезают из JSON-строки, что ломает API, если не заменить их на null.
- Нестрогое сравнение с нулём —
null == 0даётfalse, хотя интуитивно можно ожидать true; null равен только null и undefined при ==. - undefined в деструктуризации — дефолтное значение подставляется только при undefined, но не при null; это часто сбивает с толку при разборе API-ответов.
- Оператор || vs ?? —
value || 'default'заменяет все falsy-значения (0, '', false), тогда какvalue ?? 'default'— только null/undefined.
Common mistakes
- Смешивать «
nullиundefined» с похожим механизмом без критерия выбора. - Игнорировать риск: неверно оценить границы применения темы «
nullиundefined» и получить хрупкое решение. - Показывать только синтаксис и не объяснять поведение в runtime или сборке.
What the interviewer is testing
- Объясняет явное отсутствие значения против неинициализированного или отсутствующего значения.
- Показывает на примере, как работает:
undefinedчасто появляется по умолчанию при отсутствии свойства или return, аnullобычно используется как намеренный пустой результат в контракте API. - Называет production-нюанс и граничный случай для темы «
nullиundefined».