НейроАгент

Полное руководство по проверке null, undefined и пустых значений в JavaScript

Узнайте, как правильно проверять переменные на null, undefined и пустые значения в JavaScript. Изучите крайние случаи, лучшие практики и надежные реализации для надежной валидации переменных.

Вопрос

Какова стандартная функция JavaScript для проверки переменных на null, undefined или пустые значения? Я создал эту функцию для валидации значений переменных, но не уверен, охватывает ли она все случаи:

javascript
function isEmpty(val){
    return (val === undefined || val == null || val.length <= 0) ? true : false;
}

Правильно ли эта реализация обрабатывает все крайние случаи для проверки наличия значения в переменной в JavaScript?

НейроАгент

Ваша созданная функция JavaScript имеет несколько проблем, которые мешают ей корректно обрабатывать все крайние случаи. Ваша функция isEmpty не должным образом обрабатывает различные типы данных и будет вызывать ошибки в определенных сценариях.

Давайте проанализируем проблемы вашей текущей реализации:

  1. Избыточная проверка на undefined: Условие val === undefined избыточно, так как val == null уже соответствует как null, так и undefined из-за принуждения типов в JavaScript.

  2. Ошибки при доступе к свойству length: Проверка val.length <= 0 вызовет ошибки для многих типов данных, которые не имеют свойства length, таких как числа, булевы значения, даты и большинство объектов.

  3. Пропущенные крайние случаи: Ваша функция не обрабатывает строки, содержащие только пробельные символы, пустые массивы, пустые объекты или специальные значения, такие как NaN.

Вот улучшенная версия, которая обрабатывает все эти случаи:

javascript
function isEmpty(val) {
    // Проверка на null, undefined или пустую строку
    if (val == null || val === '') {
        return true;
    }
    
    // Проверка строки, содержащей только пробельные символы
    if (typeof val === 'string' && val.trim() === '') {
        return true;
    }
    
    // Проверка массивов со свойством length
    if (Array.isArray(val) && val.length === 0) {
        return true;
    }
    
    // Проверка пустых объектов (кроме массивов)
    if (typeof val === 'object' && val !== null && !Array.isArray(val) && 
        Object.keys(val).length === 0) {
        return true;
    }
    
    // Специальная обработка NaN
    if (typeof val === 'number' && isNaN(val)) {
        return true;
    }
    
    return false;
}

Содержание

Распространенные крайние случаи и решения

1. Базовые проверки на null и undefined

javascript
// Простая проверка на null/undefined
if (val == null) {
    return true;
}

Это единственное условие охватывает и null, и undefined благодаря правилам нестрогого равенства в JavaScript.

2. Валидация строк

javascript
// Проверка пустых или содержащих только пробелы строк
if (typeof val === 'string') {
    return val.trim() === '';
}

Это обрабатывает как пустые строки (""), так и строки, содержащие только пробельные символы.

3. Валидация массивов

javascript
// Проверка пустых массивов
if (Array.isArray(val)) {
    return val.length === 0;
}

Альтернативные реализации

Комплексная функция isEmpty

javascript
function isEmpty(val) {
    // Проверка на null/undefined
    if (val == null) return true;
    
    // Проверка строки (включая пробельные символы)
    if (typeof val === 'string') return val.trim() === '';
    
    // Проверка массива
    if (Array.isArray(val)) return val.length === 0;
    
    // Проверка объекта (кроме массивов и null)
    if (typeof val === 'object' && val !== null && !Array.isArray(val)) {
        return Object.keys(val).length === 0;
    }
    
    // Проверка NaN
    if (typeof val === 'number' && isNaN(val)) return true;
    
    // Для других типов считаем их непустыми
    return false;
}

Реализация в стиле Lodash

javascript
function isEmpty(val) {
    if (val == null) return true;
    
    if (typeof val === 'string' || Array.isArray(val)) {
        return val.length === 0;
    }
    
    if (typeof val === 'object') {
        return Object.keys(val).length === 0;
    }
    
    if (typeof val === 'number' && isNaN(val)) return true;
    
    return false;
}

Функции валидации для конкретных типов

Для более детального контроля вы можете использовать отдельные функции для разных типов:

javascript
// Проверка, является ли переменная null или undefined
function isNullish(val) {
    return val == null;
}

// Проверка, является ли строка пустой или содержащей только пробелы
function isBlankString(str) {
    return typeof str === 'string' && str.trim() === '';
}

// Проверка, является ли массив пустым
function isEmptyArray(arr) {
    return Array.isArray(arr) && arr.length === 0;
}

// Проверка, является ли объект пустым
function isEmptyObject(obj) {
    return typeof obj === 'object' && obj !== null && 
           !Array.isArray(obj) && Object.keys(obj).length === 0;
}

Вопросы производительности

  1. Порядок проверок: Размещайте наиболее частые проверки первыми для лучшей производительности.

  2. Избегайте ненужной проверки типов: Если вы знаете ожидаемый тип, можно пропустить некоторые проверки.

  3. Доступ к свойствам объекта: Обращение к Object.keys() имеет некоторую накладную нагрузку, поэтому подумайте, действительно ли вам это нужно.

Лучшие практики для валидации переменных

1. Будьте конкретны в своих требованиях

  • Нужно ли различать разные типы “пустоты”?
  • Следует ли считать false пустым?
  • Следует ли считать 0 пустым?

2. Рассмотрите возможность использования библиотек

Популярные библиотеки, такие как Lodash, предоставляют надежные реализации:

javascript
// Использование Lodash
import _ from 'lodash';

// isEmpty Lodash обрабатывает все случаи
_.isEmpty(val); // Возвращает true для null, undefined, "", [], {}, и т.д.

3. Документируйте поведение вашей валидации

Всегда документируйте, что ваша функция считает “пустым”, чтобы избежать путаницы:

javascript
/**
 * Проверяет, считается ли значение "пустым"
 * - Возвращает true для: null, undefined, '', [], {}, NaN
 * - Возвращает false для: false, 0, ' ', [1], {a: 1}
 * @param {*} val - Проверяемое значение
 * @returns {boolean} True, если значение пустое, иначе false
 */
function isEmpty(val) {
    // реализация
}

Тестирование вашей функции валидации

Вот как протестировать вашу функцию против различных крайних случаев:

javascript
// Тестовые случаи
const testCases = [
    { input: null, expected: true, description: 'null' },
    { input: undefined, expected: true, description: 'undefined' },
    { input: '', expected: true, description: 'пустая строка' },
    { input: '   ', expected: true, description: 'строка с пробелами' },
    { input: [], expected: true, description: 'пустой массив' },
    { input: {}, expected: true, description: 'пустой объект' },
    { input: NaN, expected: true, description: 'NaN' },
    { input: false, expected: false, description: 'булево значение false' },
    { input: 0, expected: false, description: 'число ноль' },
    { input: 'hello', expected: false, description: 'непустая строка' },
    { input: [1, 2, 3], expected: false, description: 'непустой массив' },
    { input: { a: 1 }, expected: false, description: 'непустой объект' }
];

// Запуск тестов
testCases.forEach(({ input, expected, description }) => {
    const result = isEmpty(input);
    const passed = result === expected;
    console.log(`${description}: ${passed ? '✓' : '✗'} (Ожидалось: ${expected}, Получено: ${result})`);
});

Ваша исходная функция не проходит несколько из этих тестов и вызывала бы ошибки для входных данных, таких как 0, false или {}. Улучшенные реализации выше безопасно и последовательно обрабатывают все эти случаи.

Источники

  1. MDN Web Docs - Сравнения равенства и идентичности
  2. MDN Web Docs - Оператор typeof
  3. MDN Web Docs - Object.keys()
  4. Документация Lodash - isEmpty
  5. JavaScript.info - Преобразование типов

Заключение

Ваша исходная функция имеет несколько критических недостатков, которые делают ее небезопасной для использования в продакшене. Основные проблемы включают:

  1. Ошибки времени выполнения при доступе к .length для неитерируемых типов
  2. Избыточные проверки, которые не улучшают функциональность
  3. Пропущенные крайние случаи, такие как строки с пробелами, пустые объекты и NaN

Улучшенные реализации, предоставленные выше, безопасно и последовательно обрабатывают все распространенные типы данных JavaScript. Для кода в продакшене рассмотрите использование проверенных библиотек, таких как isEmpty() из Lodash, которая была тщательно протестирована и оптимизирована.

При реализации валидации переменных в JavaScript всегда:

  • Обрабатывайте все типы данных без вызова ошибок
  • Будьте четкими в том, что constitutes “пустое” в вашем контексте
  • Документируйте поведение вашей валидации
  • Тщательно тестируйте против крайних случаев

Хотите, чтобы я подробнее рассказал о каком-либо конкретном аспекте валидации переменных или предоставил дополнительные примеры для конкретных случаев использования?