Преобразование строки в ссылку на объект JavaScript
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
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
.
Трудности работы с объектами
В JavaScript иногда процесс управления объектами может быть сложным, особенно при работе с глубоко вложенными свойствами или данными, которые мы должны отобразить пользователю. В таких ситуациях важно вооружиться эффективным и надёжным решением.
Не только чтение, но и обновление свойств
Мы продемонстрировали функцию чтения значения свойства объекта по его пути. Но что, если требуется обновить это значение? Ниже представлен вариант решения на JavaScript:
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, мы идём в ногу со временем!
Эта функция преобразует строковый путь в ключи объекта и заменяет значение последнего указанного свойства на новое.
Рекурсивный способ обхода
Если подпитано стремление изменить подход к решению, рекурсия становится отличной опцией:
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 может быть отличным помощником.
// С учетом того, что Lodash уже подключен к проекту
const value = _.get(data, 'a.b.c');
Применяя всего одну строку кода с методом _.get
, принадлежащем Lodash, можно безопасно добраться до глубоких свойств объекта. Не стоит беспокоиться о подключении всей библиотеки – lodash.get
можно установить как отдельный модуль через npm.
Визуализация
Предлагаю наглядное объяснение. Вам, вероятно, известны художники, которые создают свои работы, нанося разные слои краски на холст. Теперь представьте путь в формате one.two.three
, где каждая точка отделяет новый слой на картинах наших объектов.
let path = "one.two.three";
let objectPainting = { one: { two: { three: "Шедевр" } } };
Раскрываем слои:
🧑🎨: Обращается к полотну с названием `objectPainting`.
🎨: Наносит грунтовку `one`.
🖌️: Добавляет на неё слой `two`.
🖼️: Завершает работу, раскрывая последний слой `three`, где и обнаруживается "Шедевр".
Такая аналогия помогает визуализировать, как мы получаем доступ к данным в объекте по указанному пути.
Как защитить свой код от монстра под названием eval
Может показаться простым решением привлечение eval
для трансформации строкового пути в ссылки на объекты. Однако, его использование сопряжено со значительными рисками, это как договор с монстром! 🐲 Eval
может создать серьёзные уязвимости, особенно при обработке пользовательских данных. Поэтому лучше придерживаться безопасных подходов, описанных выше.
Управление неожиданным: обработка ошибок и значения по умолчанию
На практике часто встречаются случаи, когда путь может вернуть undefined
. Для таких ситуаций предусмотрено значение по умолчанию:
const resolvePathWithDefault = (object, path, defaultValue = undefined) => path.split('.').reduce((o, k) => (o || {})[k], object) || defaultValue;
Сотрудничество с Object.assign
В процессе создания наших объектных картин возможно мы захотим добавить новые слои.
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
гарантирует безопасное и надёжное добавление новых свойств в объект.
Полезные материалы
- Работа с объектами в JavaScript | MDN
- Как работать со вложенными объектами, массивами или JSON в JavaScript? | Stack Overflow
- Учебник по доступу к элементам объектов в JavaScript | DigitalOcean
- Геттеры и сеттеры свойств в JavaScript | javascript.info
- Официальная документация Lodash
- GitHub проект Lodash – современная библиотека утилит JavaScript для модульности и производительности
- Функция eval() в JavaScript | MDN