Паттерн Proxy (Прокси), теория

Паттерн Proxy (Прокси) применяется к объектам. Прокси — это специальная прослойка между объектом и тем, кто к нему обращается. Эта прослойка может перехватывать и контролировать все взаимодействия с объектом. То есть появляется возможность базовые операции с объектом (get, set, delete…) дополнить нужной логикой, переопределить или вовсе отменить.

На схеме обращение к объекту проходит не напрямую, а через прокси, который уже в свою очередь может выполнить какое-то дополнительное действие в момент вызова (залогировать, проверить «права доступа», дополнить или скорректировать ответ) и затем уже направить запрос непосредственно к объекту:

Схема паттерна Proxy

В JS паттерн Proxy проще всего реализовать с помощью одноимённого объекта в языке — Proxy. Берём обычный объект в JS, создаём для него прокси-объект, получаем возможность перехватывать и дополнять/переопределять операции, совершаемые с объектом:

// Целевой объект
const target = {
message1: "hello",
message2: "everyone",
};
// Прокси-объект
const handler = {
get(target, prop) {
console.log(`Свойство ${prop} считалось`);
return target[prop];
},
set(target, prop, value) {
console.log(`Свойству ${prop} задано значение ${value}`);
target[prop] = value;
return true;
},
};
// Proxy принимает в параметрах целевой объект
// и прокси-объект, который будет «перехватывать» вызовы
const proxiedObj = new Proxy(target, handler);
proxiedObj.message1;
// log: Свойство message1 считалось
proxiedObj.message2 = "nobody";
// log: Свойству message2 задано значение nobody

Какие юзкейсы есть у Proxy:

Но стоит помнить, что добавление «перегрузки» базовым методам объектов имеет свою цену: в зависимости от того кода, который написан внутри «перехватчика», время выполнения операции с объектом неминуемо увеличится. Так что злоупотреблять Proxy не стоит.