Как проверить null и undefined в JavaScript: полное руководство
Для кого эта статья:
- Программисты и разработчики, работающие с JavaScript
- Студенты и новички в веб-разработке
Технические специалисты, занимающиеся отладкой и улучшением кода
Представьте: ваше приложение на JavaScript рухнуло посреди презентации клиенту. Причина? Банальная — вы не проверили значение переменной, которое оказалось undefined. Ежедневно тысячи разработчиков сталкиваются с подобными проблемами, теряя часы на отладку и рискуя репутацией. Корректная проверка переменных — это не просто хорошая практика, а необходимость, определяющая надёжность вашего кода. В этой статье разберём всё, что нужно знать о проверке на null, undefined и пустые значения в JavaScript. 💪
Устали от багов из-за непроверенных переменных? Хотите писать код, который не "взрывается" от неожиданных undefined? В курсе Обучение веб-разработке от Skypro вы научитесь не просто решать такие проблемы, но и предотвращать их. Наши студенты осваивают профессиональные техники валидации данных, создания надёжных приложений и пишут код, которым не стыдно поделиться с коллегами. Присоединяйтесь — и ваш JavaScript станет надёжнее уже через месяц!
Что такое null, undefined и пустые значения в JavaScript
JavaScript отличается от многих языков программирования своим особым подходом к "пустым" значениям. Вместо единого представления отсутствующих данных, язык предлагает целый спектр вариантов, каждый со своей семантикой и нюансами. 🕵️♂️
Прежде всего, важно различать основные типы "пустых" значений:
undefined— переменная объявлена, но не инициализированаnull— значение отсутствует намеренно (явное указание на отсутствие)- Пустая строка (
"") — строка без символов - Пустой массив (
[]) — массив без элементов - Пустой объект (
{}) — объект без свойств NaN— результат неудачной математической операции0иfalse— численное и логическое "пустые" значения
Рассмотрим их значения в булевом контексте:
| Значение | При приведении к Boolean | Когда возникает |
|---|---|---|
undefined | false | Переменная объявлена без значения, отсутствующее свойство объекта |
null | false | Явное присваивание, результат некоторых API-методов |
"" (пустая строка) | false | Пустой ввод пользователя, очистка строки |
0 | false | Математические вычисления, счетчики |
NaN | false | Неверные математические операции (parseInt("hello")) |
[] (пустой массив) | true (! ) | Инициализация массива, очистка массива |
{} (пустой объект) | true (! ) | Инициализация объекта без свойств |
Алексей Петров, фронтенд-разработчик
Однажды я потратил целый день, пытаясь найти баг в авторизационном модуле. Пользователи жаловались, что система иногда не запоминает их после входа. Проблема оказалась в том, что API иногда возвращал не пустую строку, а null в качестве значения токена. Моя проверка
if (token === "")не ловила этот случай. Когда я заменил её на функцию универсальной проверкиisEmpty(token), которая проверяла все типы "пустых" значений, проблема была решена. С тех пор эта функция — обязательная часть всех моих проектов.
Различие между null и undefined часто вызывает путаницу. В то время как undefined указывает на отсутствие значения по умолчанию (переменная существует, но значение не присвоено), null представляет намеренное отсутствие значения, присваиваемое программистом.
Интересно, что при проверке равенства через == (без строгого равенства) null == undefined вернет true, но null === undefined вернет false, что подчеркивает важность понимания типов при проверке переменных.

Основные методы проверки переменных на пустоту
Профессиональные разработчики используют различные методы проверки переменных в зависимости от конкретных требований и контекста. Рассмотрим основные техники и их особенности. 🔍
Проверка на undefined и null
Самый базовый метод — прямое сравнение:
// Проверка на undefined
if (variable === undefined) {
console.log('Переменная не определена');
}
// Проверка на null
if (variable === null) {
console.log('Переменная имеет значение null');
}
// Проверка на undefined ИЛИ null
if (variable === undefined || variable === null) {
console.log('Переменная пуста');
}
Для более компактной записи можно использовать оператор нестрогого равенства, который считает null и undefined равными:
if (variable == null) {
console.log('Переменная равна null или undefined');
}
Однако этот метод работает только для null и undefined и не охватывает другие "пустые" значения.
Использование логического контекста
Многие значения в JavaScript автоматически приводятся к false при использовании в логическом контексте:
if (!variable) {
console.log('Переменная пуста или имеет "ложное" значение');
}
Этот подход прост, но имеет подводные камни — значения 0, пустая строка "", false, NaN также приводятся к false, в то время как пустые массивы [] и объекты {} приводятся к true.
Использование оператора typeof
Оператор typeof позволяет проверить тип переменной:
if (typeof variable === 'undefined') {
console.log('Переменная не определена');
}
Преимущество этого метода в том, что он не вызывает ошибку ReferenceError, даже если переменная вообще не объявлена.
Проверка пустых строк, массивов и объектов
Для более специфичных проверок используются различные методы:
// Пустая строка
if (str === '') {
console.log('Строка пуста');
}
// Пустой массив
if (Array.isArray(arr) && arr.length === 0) {
console.log('Массив пуст');
}
// Пустой объект
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
console.log('Объект пуст');
}
| Метод проверки | Преимущества | Недостатки |
|---|---|---|
Строгое сравнение === | Точность, явность намерений | Требует отдельных проверок для разных типов |
Нестрогое сравнение == null | Охватывает null и undefined | Не работает с другими пустыми значениями |
Логический контекст if(!var) | Лаконичность, широкий охват | Считает 0 и "" пустыми, но не {} и [] |
typeof | Безопасность с необъявленными переменными | Ограниченность (только для undefined) |
Специфичные методы (length, Object.keys()) | Точность для конкретных типов данных | Требует знания типа заранее |
Выбор метода проверки должен зависеть от конкретной ситуации и требований к обработке данных. В реальных проектах часто требуется комбинация различных подходов.
Создание универсальной функции для проверки всех типов
При разработке сложных приложений возникает необходимость в универсальном решении, которое покрывало бы все возможные случаи проверки на пустоту. Создадим функцию isEmpty, которая надежно работает со всеми типами данных JavaScript. 🛡️
Вот пример такой функции:
/**
* Универсальная функция проверки на "пустоту"
* @param {any} value – проверяемое значение
* @returns {boolean} – true если значение "пустое", иначе false
*/
function isEmpty(value) {
// Проверка на null и undefined
if (value == null) return true;
// Проверка на NaN
if (typeof value === 'number' && isNaN(value)) return true;
// Проверка на пустую строку
if (typeof value === 'string' && value.trim() === '') return true;
// Проверка на пустой массив
if (Array.isArray(value) && value.length === 0) return true;
// Проверка на пустой объект
if (typeof value === 'object' && Object.keys(value).length === 0 && value.constructor === Object) return true;
// Проверка на false
if (value === false) return true;
// Проверка на 0
if (value === 0) return true;
return false;
}
Функция последовательно проверяет все возможные типы "пустых" значений. При необходимости её можно настроить под свои потребности. Например, если в вашем приложении 0 или пустой массив [] не должны считаться пустыми значениями, вы можете убрать соответствующие проверки.
Для более гибкого использования можно создать функцию с возможностью конфигурирования:
/**
* Настраиваемая функция проверки на "пустоту"
* @param {any} value – проверяемое значение
* @param {Object} options – настройки проверки
* @returns {boolean} – true если значение "пустое", иначе false
*/
function isEmptyCustom(value, options = {}) {
const defaults = {
treatZeroAsEmpty: true,
treatFalseAsEmpty: true,
treatEmptyArrayAsEmpty: true,
treatEmptyObjectAsEmpty: true,
trimStrings: true
};
const settings = { ...defaults, ...options };
// Проверка на null и undefined
if (value == null) return true;
// Проверка на NaN
if (typeof value === 'number' && isNaN(value)) return true;
// Проверка на пустую строку
if (typeof value === 'string') {
return settings.trimStrings ? value.trim() === '' : value === '';
}
// Проверка на пустой массив
if (Array.isArray(value) && value.length === 0) {
return settings.treatEmptyArrayAsEmpty;
}
// Проверка на пустой объект
if (typeof value === 'object' && Object.keys(value).length === 0 && value.constructor === Object) {
return settings.treatEmptyObjectAsEmpty;
}
// Проверка на false
if (value === false) return settings.treatFalseAsEmpty;
// Проверка на 0
if (value === 0) return settings.treatZeroAsEmpty;
return false;
}
Теперь вы можете указать, какие типы пустых значений следует учитывать:
// Проверка, игнорирующая 0 и false как пустые значения
const result = isEmptyCustom(value, {
treatZeroAsEmpty: false,
treatFalseAsEmpty: false
});
Такая универсальная функция особенно полезна при валидации форм, обработке API-ответов и всех ситуациях, где требуется надёжная проверка данных перед их использованием.
Сергей Волков, тимлид JavaScript-разработки
В нашем проекте с микросервисной архитектурой мы столкнулись с настоящим хаосом в обработке пустых значений. Каждый сервис возвращал данные по-своему: где-то null, где-то пустые массивы, а иногда даже строку "null". Мы тратили огромное количество времени на отладку проблем, связанных с непредсказуемыми данными.
Решение пришло, когда мы внедрили универсальную функцию проверки isEmpty() во все фронтенд-компоненты. Эта функция учитывала все возможные формы "пустоты" и давала предсказуемые результаты. Количество багов сократилось на 40%, а времени на разработку новых фич стало больше. Самое важное — мы стандартизировали подход к проверке данных на всём проекте, что значительно упростило код-ревью и онбординг новых разработчиков.
Типичные ошибки при проверке на null и undefined
Даже опытные разработчики допускают ошибки при проверке переменных на пустоту. Рассмотрим наиболее распространенные ловушки и способы их избежать. ⚠️
Ошибка #1: Неправильное использование оператора равенства
Одна из классических ошибок — неправильное использование операторов == и ===:
// Ошибка: использование нестрогого сравнения, когда требуется строгое
if (value == undefined) { /* ... */ } // Также вернет true для null
// Ошибка: использование строгого сравнения, когда требуется проверить оба значения
if (value === undefined) { /* ... */ } // Не сработает для null
Правильный подход зависит от требований:
// Для проверки только на undefined
if (value === undefined) { /* ... */ }
// Для проверки на null или undefined
if (value == null) { /* ... */ }
// Для явной проверки на оба значения
if (value === null || value === undefined) { /* ... */ }
Ошибка #2: Проверка необъявленной переменной
Попытка проверить необъявленную переменную приведет к ошибке ReferenceError:
// Ошибка: переменная notDeclared не объявлена
if (notDeclared === null) { /* Вызовет ошибку */ }
Безопасный способ проверки:
// Правильно: сначала проверяем, существует ли переменная
if (typeof notDeclared === 'undefined') { /* Безопасно */ }
Ошибка #3: Неверная обработка объектов и массивов
Распространенная ошибка — неправильная проверка пустоты объектов и массивов:
// Ошибка: логическое преобразование не определяет пустоту
if (!array) { /* Не сработает для [] */ }
if (!object) { /* Не сработает для {} */ }
// Ошибка: прямое сравнение с пустым массивом/объектом
if (array === []) { /* Не работает, т.к. сравнивает ссылки */ }
Правильный подход:
// Правильно: проверка длины массива
if (Array.isArray(array) && array.length === 0) { /* ... */ }
// Правильно: проверка ключей объекта
if (Object.keys(object).length === 0 && object.constructor === Object) { /* ... */ }
Ошибка #4: Игнорирование ложноположительных значений
При использовании логического контекста для проверки, важно помнить, какие значения приводятся к false:
// Ошибка: некоторые не-пустые значения воспринимаются как пустые
if (!value) {
// Сработает для 0, '', false – хотя они могут быть валидными данными
}
Более точный подход:
// Правильно: явная проверка на интересующие нас "пустые" значения
if (value === null || value === undefined || value === '') {
// Более целенаправленная проверка
}
Ошибка #5: Ненадежная проверка вложенных свойств
Часто возникают ошибки при доступе к свойствам потенциально отсутствующих объектов:
// Ошибка: вызовет ошибку, если user равен null или undefined
if (user.profile.name === null) { /* Потенциальная ошибка */ }
Безопасные альтернативы:
// Правильно: проверка на каждом уровне
if (user && user.profile && user.profile.name === null) { /* ... */ }
// Современно: использование опционального оператора (ES2020+)
if (user?.profile?.name === null) { /* ... */ }
- Всегда выбирайте подходящий тип проверки в зависимости от контекста
- Используйте опциональную цепочку (
?.) для безопасного доступа к вложенным свойствам - Помните о различиях между
==и===при проверке на null/undefined - Учитывайте, что пустые объекты и массивы приводятся к
trueв логическом контексте - Будьте осторожны с трактовкой значений
0,""иfalseкак пустых
Оптимальные практики проверки переменных в проектах
Стабильная кодовая база требует согласованного подхода к проверке переменных. Рассмотрим лучшие практики, которые помогут стандартизировать и оптимизировать работу с пустыми значениями в ваших проектах. 📊
Стандартизация подхода в команде
Согласованность — ключ к поддерживаемому коду. Выберите и документируйте единый подход к проверке переменных:
- Создайте общую утилиту для проверки пустых значений, которую будут использовать все члены команды
- Включите правила проверки переменных в стайл-гайд команды
- Настройте линтеры (например, ESLint) для автоматической проверки соответствия правилам
- Проводите код-ревью с особым вниманием к правильности проверок переменных
Пример правила ESLint для предотвращения сравнения с undefined напрямую:
// .eslintrc.js
module.exports = {
"rules": {
"no-undefined": "error",
"eqeqeq": ["error", "always"]
}
}
Использование современных возможностей JavaScript
JavaScript постоянно эволюционирует, предоставляя новые инструменты для элегантного решения проблем с пустыми значениями:
// Оператор опциональной цепочки (?.) – ES2020
const userName = user?.profile?.name ?? 'Гость';
// Оператор нулевого слияния (??) – ES2020
const count = data?.count ?? 0;
// Деструктуризация с значениями по умолчанию – ES6
const { title = 'Без названия', description = '' } = article || {};
// Параметры функций по умолчанию – ES6
function processData(data = {}, options = { validate: true }) {
// ...код...
}
Эти возможности позволяют писать более чистый и выразительный код, уменьшая количество явных проверок.
Дифференцированный подход к разным типам данных
Разные типы данных требуют разных подходов к проверке:
| Тип данных | Рекомендуемый подход | Пример использования |
|---|---|---|
| Примитивы (string, number) | Специфичные проверки для каждого типа | string === '' || number === 0 |
| Объекты (включая null) | Проверка на null + проверка ключей | obj === null || Object.keys(obj).length === 0 |
| Массивы | Проверка на Array.isArray + length | !Array.isArray(arr) || arr.length === 0 |
| Функции | Проверка типа через typeof | typeof fn !== 'function' |
| Вложенные структуры | Опциональная цепочка | data?.users?.[0]?.name |
Обработка пустых значений в различных контекстах
Стратегия проверки должна соответствовать контексту использования:
- Валидация форм: проверка всех типов пустых значений с учетом требований полей
- API-запросы: проверка полноты ответа перед использованием данных
- Бизнес-логика: четкое определение, какие значения считать пустыми для конкретной логики
- Рендеринг UI: условный рендеринг с учетом возможных пустых значений
- Хранение данных: нормализация данных перед сохранением
Пример обработки различных контекстов:
// Для валидации форм
function validateField(value, fieldType) {
if (fieldType === 'required' && (value === null || value === undefined || value === '')) {
return 'Поле обязательно для заполнения';
}
if (fieldType === 'email' && !isValidEmail(value)) {
return 'Введите корректный email';
}
return null; // Валидация успешна
}
// Для API-запросов
async function fetchUserData(userId) {
try {
const response = await api.getUser(userId);
if (!response || !response.data) {
throw new Error('Пустой ответ от API');
}
return response.data;
} catch (error) {
logError(error);
return null;
}
}
Предпочтение явных проверок над неявными
Хотя краткость — сестра таланта, при проверке переменных предпочтительнее явные и читаемые проверки:
// Менее предпочтительно: неявная проверка через приведение типов
if (!value) {
// Неочевидно, что именно проверяется
}
// Предпочтительно: явная проверка с понятным намерением
if (value === null || value === undefined || value === '') {
// Ясно, какие значения считаются пустыми
}
Явные проверки делают код более поддерживаемым и понятным для других разработчиков.
Главное в проверке переменных — последовательность и адаптация к контексту. Стремитесь к балансу между краткостью кода и его читаемостью, используйте современный синтаксис JavaScript и автоматизируйте проверку согласованности через инструменты статического анализа. Следуя этим практикам, вы значительно повысите надежность и поддерживаемость вашего кода. 🚀
Грамотная проверка переменных на null, undefined и пустые значения — не просто техническая формальность, а фундамент надежного JavaScript-кода. Создав универсальную функцию isEmpty() и следуя описанным выше практикам, вы защитите свои приложения от непредвиденных ошибок и значительно сократите время отладки. Но помните — даже лучшие инструменты требуют осознанного применения. Анализируйте контекст, выбирайте подходящие методы проверки и стандартизируйте подход в своей команде. Когда-нибудь вы скажете спасибо самому себе за то, что уделили должное внимание этой "мелочи".