Проверка существования вложенного ключа в JavaScript объекте

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Прежде чем погрузиться в теорию, вот вам функция для проверки ключа во вложенном объекте:

JS
Скопировать код
const keyExists = (obj, path) => path.split('.').every(key => {
  return (obj = obj?.[key]) !== undefined;
});

// Пример применения:
const obj = { a: { b: { c: 1 } } };
console.log(keyExists(obj, 'a.b.c')); // true
console.log(keyExists(obj, 'a.b.c.d')); // false

Эта функция использует split('.') вместе с every(), позволяя проверять ключи последовательно. Также здесь использована конструкция obj?.[key] для безопасного доступа ко вложенным объектам.

Кинга Идем в IT: пошаговый план для смены профессии

Изучаем опциональное цепочное объединение и метод reduce

Введение в опциональное цепочное объединение

Опциональное цепочное объединение ?. служит для проверки существования вложенных свойств без необходимости явного контроля на каждом уровне. Это усовершенствование было внесено в ECMAScript 2020 для удобства разработчиков:

JS
Скопировать код
// Безопасный доступ к глубоко вложенному свойству
const value = obj?.a?.b?.c; // Если путь отсутствует, вернется undefined

// Безопасный вызов метода...
const result = obj?.a?.b?.myMethod?.(); // Если метод отсутствует, вернется undefined

Используем reduce для функционального подхода

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

JS
Скопировать код
const nestedKeyExists = (obj, path) => path.split('.').reduce((acc, key) => acc?.[key], obj) !== undefined;

Рефакторинг с помощью lodash и изящных паттернов

Применим lodash

При работе с вложенными объектами может оказаться полезной библиотека Lodash. Метод _.get позволяет безопасно извлечь вложенные свойства:

JS
Скопировать код
const _ = require('lodash');

const value = _.get(obj, 'a.b.c', 'default');

Также возможно использовать массивы для сложных путей:

JS
Скопировать код
// Пути в виде массивов ключей – почему бы и нет?
const value = _.get(obj, ['a', 'b', 'c'], 'default');

Применяем паттерны кодирования

Паттерн Оливера Стиля подойдет вам для изящного обращения к вложенным свойствам:

JS
Скопировать код
// Элегантный доступ к свойствам с использованием паттерна Оливера Стила
const value = (((obj || {}).a || {}).b || {}).c;

Осваиваем будущее с Babel

Чтобы обеспечить совместимость кода с различными браузерами и использовать современные возможности JavaScript, вы можете воспользоваться Babel:

json
Скопировать код
{
  "plugins": ["@babel/plugin-proposal-optional-chaining"]
}

С Babel версии 7.8.0 и выше, вы получаете возможность использовать новые возможности JavaScript, которые ещё только становятся стандартом.

Избегаем подводных камней: лучшие практики

Следуем простоте

KISS (Keep It Simple, Stupid)! Избегайте ненужно сложных конструкций и трюков (например, Reflect.has). Лаконичность – превыше всего!

Заботимся о памяти

Контролируйте, как вы используете ссылки, и избегайте создания лишних замыканий. Размещайте ваш код логично.

Обеспечиваем совместимость с браузерами

Убедитесь, что нужные функции поддерживают вашу среду выполнения. Для этого вы можете использовать такие инструменты, как "caniuse" или таблицы совместимости Babel.

Осваиваем работу с вложенностью

Значение по умолчанию – наш страховой механизм

Укажите значение по умолчанию, чтобы избежать неопределённых значений:

JS
Скопировать код
const safeAccess = (obj, path) => path.split('.').reduce((acc, key) => acc ? acc[key] : {}, obj);
const defaultValue = safeAccess(obj, 'a.b.c') || 'default';

Ключи-миксы? Отличное решение!

Если ваши пути включают индексы массива или переменные ключи, адаптируйте свои функции, чтобы они учитывали разнообразные сценарии:

JS
Скопировать код
const isValidPath = (obj, path) => {
  return path.split('.').reduce((acc, key) => {
    if (acc && key in acc) return acc[key];
    // Не забываем про обработку массивов и их индексов
    if (Array.isArray(acc) && !isNaN(key)) return acc[key];
    return undefined;
  }, obj);
};

Гибкость при работе с вложенностью

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

Визуализация

Представьте себе задачу нахождения пути в лабиринте:

plaintext
Скопировать код
Start: Entrance (🚪)
Goal: Find the Treasure Room (🏆)

Проверка наличия пути в объекте – это как поиск маршрута через лабиринт:

JS
Скопировать код
// Проход по лабиринту аналогичен обращению к ключам вложенного объекта
const labyrinth = {
  room1: {
    room2: {
      treasureRoom: "🏆"
    }
  }
};

function hasPath(obj, path) {
  return path.reduce((o, key) => (o && o[key] != null) ? o[key] : false, obj);
}

// Нет минотавра в комнатах 1 и 2, к счастью 🐂
hasPath(labyrinth, ['room1', 'room2', 'treasureRoom']); // Вернёт 🏆

Успех!

Markdown
Скопировать код
Путь найден: 🚪 ➡️ 🏆
Лабиринт покорен, сокровище у нас в руках. Время для победного танца! 🙌

Полезные материалы

  1. Опциональное цепочное объединение (?.) – JavaScript | MDN — MDN рассказывает об опциональном цепочном объединении.
  2. Проверка существования ключа во вложенном объекте JavaScript – Stack Overflow — интересные обсуждения на Stack Overflow.
  3. Документация Lodash — изучаем метод get в Lodash: извлечение вложенных свойств как ниндзя.
  4. Опциональное цепочное объединение · V8 — подробности о нововведениях от разработчиков V8, вошедших в ECMAScript 2020.
  5. Опциональное цепочное объединение '?.' – javascript.info — учебник с заданиями и примерами.
  6. Лучшие практики JavaScript – W3C Wiki — рекомендации для написания качественного и поддерживаемого кода.
  7. npm: Плагин ESLint для безопасного использования опционального цепочного объединения — полезный плагин ESLint для вашего кода.