null и undefined

null — явное отсутствие значения (пусто намеренно). undefined — значение не было присвоено (пусто случайно).

Зачем нужно

Понимание разницы между null и undefined предотвращает ошибки при работе с данными, API и DOM. Это два разных «ничего», и их путаница — частый источник багов.

Где используется

  • Инициализация переменных
  • Возврат из функций
  • Проверка существования данных
  • Работа с API (null-поля в JSON)
  • DOM (отсутствие элемента)

Предпосылки

Типы данных, Boolean

undefined — «не задано»

// 1. Переменная объявлена, но не присвоена
let x;
console.log(x); // undefined

// 2. Несуществующее свойство объекта
const user = { name: 'Алиса' };
console.log(user.age); // undefined

// 3. Параметр функции не передан
function greet(name) {
  console.log(name); // undefined если не передать
}
greet;

// 4. Функция без return
function doNothing() {
  // нет return
}
console.log(doNothing); // undefined

// 5. void оператор
console.log(void 0); // undefined

null — «намеренно пусто»

// 1. Явная инициализация «ничем»
let selectedUser = null; // Пользователь ещё не выбран

// 2. Очистка ссылки
let data = { items: [1, 2, 3] };
data = null; // Освобождаем объект для сборщика мусора

// 3. Значение по умолчанию в API
const response = {
  user: null, // Пользователь не найден
  error: null // Ошибок нет
};

// 4. DOM — элемент не найден
const element = document.querySelector('#nonexistent');
console.log(element); // null

Сравнение null и undefined

// typeof
typeof undefined; // "undefined"
typeof null;      // "object" — исторический баг!

// Нестрогое равенство (==)
null == undefined;  // true — считаются равными
null == 0;          // false
null == '';         // false
null == false;      // false
undefined == 0;     // false
undefined == '';    // false
undefined == false; // false

// Строгое равенство (===)
null === undefined; // false — разные типы
null === null;      // true
undefined === undefined; // true

// Арифметика
null + 5;       // 5 (null -> 0)
undefined + 5;  // NaN (undefined -> NaN)
Number(null);   // 0
Number(undefined); // NaN

// Boolean
Boolean(null);      // false
Boolean(undefined); // false

Проверка на null/undefined

// Проверка конкретно null
if (value === null) { /* точно null */ }

// Проверка конкретно undefined
if (value === undefined) { /* точно undefined */ }
if (typeof value === 'undefined') { /* безопасно даже для необъявленных */ }

// Проверка на оба (null или undefined)
if (value == null) { /* null ИЛИ undefined */ }
// Это единственное место, где == вместо === оправдан

// Nullish coalescing (??)
const name = value ?? 'default'; // default если null/undefined

// Optional chaining (?.)
const city = user?.address?.city; // undefined вместо TypeError

Паттерны использования

Инициализация

// Для ссылочных типов — null
let currentUser = null;
let cachedData = null;

// Для примитивов — часто undefined по умолчанию
let count; // undefined — ещё не подсчитано

Проверка наличия данных

function processUser(user) {
  // Проверка на null/undefined
  if (user == null) {
    console.log('Пользователь не задан');
    return;
  }

  // Optional chaining для вложенных свойств
  const email = user.contacts?.email ?? 'не указан';
  console.log(`Email: ${email}`);
}

processUser(null);                // 'Пользователь не задан'
processUser({ name: 'Алиса' });  // 'Email: не указан'
processUser({ name: 'Боб', contacts: { email: 'bob@mail.com' } });
// 'Email: bob@mail.com'

JSON и null

// JSON поддерживает null, но не undefined
const data = { a: null, b: undefined, c: 42 };
JSON.stringify(data); // '{"a":null,"c":42}' — undefined пропущен
JSON.parse('{"a": null}'); // { a: null }

Частые ошибки

1. Доступ к свойствам null/undefined

const user = null;
// user.name; // TypeError: Cannot read properties of null

// Решение: optional chaining
const name = user?.name; // undefined (без ошибки)

2. Путаница == и ===

if (value == null) { /* null ИЛИ undefined — OK для этого случая */ }
if (value === null) { /* только null */ }
if (value === undefined) { /* только undefined */ }

3. typeof null === 'object'

function isObject(val) {
  // Неправильно — null тоже "object"
  // return typeof val === 'object';

  // Правильно
  return val !== null && typeof val === 'object';
}

Практика

  1. Напиши функцию, которая принимает объект и возвращает количество свойств со значением null
  2. Используй ?? для задания дефолтов: name, age, isActive
  3. Покажи разницу Number(null) vs Number(undefined)
  4. Напиши функцию безопасного доступа к вложенным свойствам без optional chaining

Связанные темы

Ресурсы


🎓 Источник: 👶 JavaScript для начинающих 4. Значения и типы

  • 📅 2021-10-02 · YouTube
  • Тезисы: undefined — "значение не определено", дано системой. null — "значение явно отсутствует", даёт программист. typeof null === 'object' — исторический баг. Они равны по == но разные типы

⚡ Источник: Существует ли приведение типа в JavaScript · AsForJS

  • 📅 2025-02-16 · YouTube
  • Тезисы: null == undefined — это спец-кейс в IsLooselyEqual. По спеке: "if x is null and y is undefined, return true". Все остальные сравнения null с числом/строкой → false (исключение: relational operators)