Преобразование строки в ссылку на объект JavaScript

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

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

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

JS
Скопировать код
const resolvePath = (object, path) => path.split('.').reduce((o, k) => (o || {})[k], object);

// Пример использования:
const data = { a: { b: { c: 2 } } };
const value = resolvePath(data, 'a.b.c'); // Возвращает 2, что логично!

Эта компактная функция использует метод reduce для последовательного обращения к вложенным свойствам. Её работа заключается в разбиении строки, разделённой точками, на ключи объекта, при отсутствии пути возвращается undefined.

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

Трудности работы с объектами

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

Не только чтение, но и обновление свойств

Мы продемонстрировали функцию чтения значения свойства объекта по его пути. Но что, если требуется обновить это значение? Ниже представлен вариант решения на JavaScript:

JS
Скопировать код
const setPath = (object, path, value) => {
  const keys = path.split('.');
  keys.reduce((o, k, i) => (o[k] = keys.length === i + 1 ? value : o[k] || {}), object);
};

// Увеличим значение 'a.b.c'
setPath(data, 'a.b.c', 3); // Теперь 'a.b.c' равно 3, мы идём в ногу со временем!

Эта функция преобразует строковый путь в ключи объекта и заменяет значение последнего указанного свойства на новое.

Рекурсивный способ обхода

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

JS
Скопировать код
function resolvePathRecursively(object, path) {
  let keys = path.split('.');
  let current = object;
  for (let key of keys) {
    if (current[key] === undefined) return undefined;
    current = current[key];
  }
  return current;
}

Данная функция делит строковый путь на ключи и последовательно углубляется в структуру объекта.

Lodash для упрощения работы с объектами

Если синтаксис JavaScript создаёт трудности, Lodash может быть отличным помощником.

JS
Скопировать код
// С учетом того, что Lodash уже подключен к проекту
const value = _.get(data, 'a.b.c');

Применяя всего одну строку кода с методом _.get, принадлежащем Lodash, можно безопасно добраться до глубоких свойств объекта. Не стоит беспокоиться о подключении всей библиотеки – lodash.get можно установить как отдельный модуль через npm.

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

Предлагаю наглядное объяснение. Вам, вероятно, известны художники, которые создают свои работы, нанося разные слои краски на холст. Теперь представьте путь в формате one.two.three, где каждая точка отделяет новый слой на картинах наших объектов.

JS
Скопировать код
let path = "one.two.three";
let objectPainting = { one: { two: { three: "Шедевр" } } };

Раскрываем слои:

Markdown
Скопировать код
🧑‍🎨: Обращается к полотну с названием `objectPainting`.
🎨: Наносит грунтовку `one`.
🖌️: Добавляет на неё слой `two`.
🖼️: Завершает работу, раскрывая последний слой `three`, где и обнаруживается "Шедевр".

Такая аналогия помогает визуализировать, как мы получаем доступ к данным в объекте по указанному пути.

Как защитить свой код от монстра под названием eval

Может показаться простым решением привлечение eval для трансформации строкового пути в ссылки на объекты. Однако, его использование сопряжено со значительными рисками, это как договор с монстром! 🐲 Eval может создать серьёзные уязвимости, особенно при обработке пользовательских данных. Поэтому лучше придерживаться безопасных подходов, описанных выше.

Управление неожиданным: обработка ошибок и значения по умолчанию

На практике часто встречаются случаи, когда путь может вернуть undefined. Для таких ситуаций предусмотрено значение по умолчанию:

JS
Скопировать код
const resolvePathWithDefault = (object, path, defaultValue = undefined) => path.split('.').reduce((o, k) => (o || {})[k], object) || defaultValue;

Сотрудничество с Object.assign

В процессе создания наших объектных картин возможно мы захотим добавить новые слои.

JS
Скопировать код
const mergeProperties = (target, path, value) => {
  let lastKeyIndex = path.lastIndexOf('.');
  let lastKey = path.substring(lastKeyIndex + 1);
  let lastObject = resolvePath(target, path.substring(0, lastKeyIndex));
  Object.assign(lastObject, { [lastKey]: value });
};

Метод Object.assign гарантирует безопасное и надёжное добавление новых свойств в объект.

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

  1. Работа с объектами в JavaScript | MDN
  2. Как работать со вложенными объектами, массивами или JSON в JavaScript? | Stack Overflow
  3. Учебник по доступу к элементам объектов в JavaScript | DigitalOcean
  4. Геттеры и сеттеры свойств в JavaScript | javascript.info
  5. Официальная документация Lodash
  6. GitHub проект Lodash – современная библиотека утилит JavaScript для модульности и производительности
  7. Функция eval() в JavaScript | MDN
Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какова роль функции `resolvePath`?
1 / 5