СвязатьсяНачать
Вернуться в блог
12.02.2024
JavaScript

DefineProperty или как следить за изменением объекта

Была у меня ситуации, когда мне было нужно модернизировать уже готовый функционал какой-то библиотеки. А точнее можно ли как-то отслеживать изменения объекта который создан на основе класса.

Сегодня поговорим про интересный 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 , которое меняется в зависимости от этапа формы на котором находится юзер. Обратите внимание, что в консоль я вывожу информацию об измененном свойстве только когда оно изменилось на странице, а не при загрузке страницы.