Проксирование изменений вложенного объекта в JavaScript? Доброго времени суток, %username%!
Итак, JavaScript. У нас имеется объект (с методами загрузки/сохранения) для хранения настроек приложения (в localstorage), и объект этот выглядит так:var SettingsStorage = {
data: {
some_value1: null,
child_object: {
some_value2: true,
some_value3: 1000
},
some_value4: null
},
load: function(callback) {
// load this.data from localstorage
},
save: function(callback) {
// save this.data to localstorage
}
};
И имеется прокси-объект для доступа к данным настроек вида:var Settings = new Proxy(SettingsStorage.data, {
set: function(obj, prop, value) {
var storage_data = SettingsStorage.data;
if (obj === storage_data && prop === 'some_value1') {
console.log('Да да! Мы поймали момент изменения SettingsStorage.data.some_value1!');
}
obj[prop] = value;
return true;
}
});
И теперь при изменении Settings.some_value1 мы изменяем SettingsStorage.data.some_value1 и можем выполнить произвольный код в момент изменения (например - сохранить изменения, что избавит нас от принудительного вызова SettingsStorage.save()).
И всё бы ничего, если бы не необходимость перехватить момент изменения SettingsStorage.data.child_object.some_value2 - с дочерними объектами этот финт не прокатывает. Как это сделать?
ps. Данный подход необходим для того, что-бы при изменении каких-либо важных настроек приложения изменить его поведение в целом. Другими словами нужно отловить изменения свойств объекта, без написания отдельного объекта с тучей геттеров/сеттеров + переписывать уже созданный апи. Браузер - Google Chrome.

21 Авг 2019 в 07:04
185 +1
0
Ответы
1

Для того чтобы отслеживать изменения во вложенных объектах, вам нужно использовать так называемый "глубокий прокси" или "рекурсивный прокси". Это позволит перехватывать изменения во всех вложенных объектах.

Вот как можно реализовать это для вашего случая:

function createDeepProxy(obj, onChange) {
const handler = {
get(target, property, receiver) {
const value = Reflect.get(target, property, receiver);
if (typeof value === 'object' && value !== null) {
return new Proxy(value, handler);
}
return value;
},
set(target, property, value, receiver) {
const success = Reflect.set(target, property, value);
if (success) {
onChange(property, value);
}
return success;
}
};
return new Proxy(obj, handler);
}
var Settings = createDeepProxy(SettingsStorage.data, function(property, value) {
console.log(`Да да! Мы поймали момент изменения SettingsStorage.data.${property}!`);
// Дополнительный код, который нужно выполнить при изменении
});

Теперь при изменении любого свойства во вложенных объектах SettingsStorage.data (например, Settings.child_object.some_value2), изменения будут перехвачены и обработаны соответствующим образом.

Надеюсь, это поможет вам решить вашу проблему! Если у вас возникнут дополнительные вопросы, пожалуйста, не стесняйтесь задавать.

20 Апр 2024 в 13:08
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир