Разделите путь по точкам и проверяйте каждый собственный ключ, останавливаясь на null, undefined или отсутствии свойства. Метод можно разместить в отдельном прототипе, не меняя Object.prototype.
Получение значения по вложенному пути в объекте
Разделите путь по точкам и проверяйте каждый собственный ключ, останавливаясь на null, undefined или отсутствии свойства. Метод можно разместить в отдельном прототипе, не меняя Object.prototype.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Имеется объект, вложенный на несколько уровней. Требуется реализовать прототипный метод hash, который принимает строку‑путь и возвращает соответствующее значение, если такой путь существует, либо undefined, если путь неверный.
const obj = {
person: {
name: "joe",
history: {
hometown: "bratislava",
bio: {
funFact: "I like fishing.",
},
},
},
};
obj.hash("person.name"); // 'joe'
obj.hash("person.history.bio"); // { funFact: 'I like fishing.' }
obj.hash("person.history.homeStreet"); // undefined
obj.hash("person.animal.pet.needNoseAntEater"); // undefined
Метод должен корректно обрабатывать любые вложенные структуры, возвращая нужные данные или undefined, когда путь не может быть разрешён.
Ответ
Разделите путь по точкам и проверяйте каждый собственный ключ, останавливаясь на null, undefined или отсутствии свойства. Метод можно разместить в отдельном прототипе, не меняя Object.prototype.
const hashPrototype = Object.create(Object.prototype, {
hash: { value: function (path) {
if (typeof path !== 'string' || path === '') return undefined;
let current = this;
for (const key of path.split('.')) {
if (current == null || !Object.hasOwn(Object(current), key)) return undefined;
current = current[key];
}
return current;
} }
});
// Для нового объекта вместо обычного литерала:
const data = Object.assign(Object.create(hashPrototype), obj);
data.hash('person.name'); // 'joe'
Чтобы сохранить именно имя obj из примера, создайте исходный объект таким способом. Унаследованные поля не читаются; ключи с точкой внутри имени потребовали бы другой схемы пути. Глобальное расширение Object.prototype затронуло бы все объекты приложения.