Сегодня поговорим про интересный Object.DefineProperty
Предисловие
Была у меня ситуации, когда мне было нужно модернизировать уже готовый функционал какой-то библиотеки. Однако библиотека представляла из себя набор из других библиотек с определенным смешанным функционалом. Проще говоря это была рабочая машина, модернизировать которую можно было только если собрать ее с нуля.
Тогда мне стало интересно, а можно ли как-то отслеживать изменения объекта который создан на основе класса из этой библиотеки, при том, что у объекта нет своих геттеров и сеттеров (соответственно MutationObserver использовать тут нельзя).
Зачем это нужно
Отслеживать я хотел не весь объект, а одно конкретное свойство. Свойство отвечало за номер этапа формы и показывало цифрой этот самый номер. Каждый раз когда в форме юзер переходил к следующему этапу, номер менялся. Однако менялся он встроенными методами самого объекта, доступа к которым у меня изначально не было. Но я мог переопределить функцию инициализации объекта до того как он будет создан при загрузке страницы. Поэтому я вывел объект в глобальную область видимости переопределив функцию инициализации и таким образом могу теперь использовать этот объект в своей функции.
Функция
Кстати давайте напишем эту функцию
function observeChangesProperty(object, propertyName, callback) {
let currentValue = object[propertyName];
Object.defineProperty(object, propertyName, {
get() {
return currentValue;
},
set(newValue) {
if (newValue !== currentValue) {
currentValue = newValue;
callback(object, propertyName, newValue);
}
},
});
}
Теперь начнем отслеживать свойство моего объекта
observeChangesProperty(myObject, 'currentStep', (object, propertyName, newValue) => {
console.log(`Property '${propertyName}' = '${newValue}'`);
});
И в данном случае я отслеживаю свойство currentStep
, которое меняется в зависимости от этапа формы на котором находится юзер. Обратите внимание, что в консоль я вывожу информацию об измененном свойстве только когда оно изменилось на странице, а не при загрузке страницы.