Полный цикл в digital

Объект Proxy

Proxy представляет объект, который позволяет перехватывать выполнение операций по отношению к некотоому объекту и переопределять его поведение. Для создания объекта Proxy применяется конструктор Proxy():

const proxy = new Proxy(target, handler);

Конструктор Proxy принимает два параметра:

  • target цель создания прокси, это может быть любой объект, к которому применяется Proxy
  • handler другой объект, который определяет, какие именно операции объекта target будут перехватываться и переопределяться и как именно

Рассмотрим простейший пример:

// объект, к которому применяется прокси
const target = {name: "Tom"};
// объект, который определяет, как будет переопределяться target
const handler = {};
// объект прокси
const proxy = new Proxy(target, handler);
// Tom
console.log(proxy.name);

Итак, в примере выше target - это объект, к которому будет применяться проксирование. В данном случае этот объект имеет свойство name.

const target = {name: "Tom"};

Далее создается пустой обработчик handler:

const handler = {};

В принципе этот объект должен определять, как будет переопределяться объект target. Но пока оставим его пустым.

Затем создаем объект Proxy, передавая в его конструктор объекты target и handler:

const proxy = new Proxy(target, handler);

Проксирование объекта (в данном случае объекта target) означает, что через прокси мы можем обращаться к функциональности этого объекта. И в данном случае через объект proxy мы можем обратиться к свойству name проксированного объекта target:

// Tom
console.log(proxy.name);

И поскольку мы использовали пустой handler, который ничего не переопределяет, то по сути прокси ведет себя как оригинальный объект target.

Переопределение функциональности объекта

Выше мы выполнили проксирование объекта, но пока никак не переопределяли его поведение. Ключевым в данном случае является определение обработчика handler, который может перехватывать обращения к свойствам проксированного объекта. Этот обработчик может определять два метода: get и set.

Метод get и получение свойств объекта

Метод get перехватывает обращения к свойству при получении его значения и возвращает для этого свойства некоторое значение:

const handler = {
get: function(target, prop, receiver) {
return некоторое_значение;
}
};

Метод get имеет три параметра:

  • target сам проксированный объект. Благодаря этому параметру мы можем обратиться к функциональности оригинального объекта
  • prop название свойства, к которому идет обращение
  • receiver объект Proxy, через который выполняется проксирование

Возьмем следующий пример:

const target = {name: "Tom"};
const handler = {
get: function(target, prop, receiver) {
return "Tomas Smith";
}
};
const proxy = new Proxy(target, handler);
// Tomas Smith
console.log(proxy.name);

Здесь в обработчике handler в методе get возвращается строка Tomas Smith:

get: function(target, prop, receiver) {
return "Tomas Smith";
}

Это приведет к тому, что при обращение к любому свойству прокси-объекта будет возвращаться данная строка:

// Tomas Smith
console.log(proxy.name);

Так, мы выполнили перехват обращения к свойству и простейшее переопределение. При этом мы можем обащаться и к оригинальному объекту, который проксируется:

const target = {name: "Tom"};
const handler = {
get: function(target, prop) {
return "Name: " + target.name;
}
};
const proxy = new Proxy(target, handler);
// Name: Tom
console.log(proxy.name);

Здесь обработчик возвращает строку "Name: " + target.name, где target.name представляет обращение к свойству name оригинального объекта. Естественно логика возвращение значения свойства может более сложной.

Но возьмем более сложный объект - с двумя свойствами:

const target = {name: "Tom", age: 37};
const handler = {
get: function(target, prop) {
return target[prop];
}
};
const proxy = new Proxy(target, handler);
// Tom
console.log(proxy.name);  
// 37
console.log(proxy.age);

Здесь целевой объект имеет два свойства: name и age. В обработчике мы перехватываем обращение к ним, но никак его не переопределяем, а просто возвращаем значения свойств оригинального объекта:

return target[prop];

Для обращения к свойствам целевого объекта применяется синтаксис массивов. Но также мы можем проверить, к какому именно свойству идет обращение, и выполнить некоторое переопределение:

const target = {name: "Tom", age: 37};
const handler = {
get: function(target, prop) {
if(prop==="name")
return target.name.toUpperCase();
else
return target[prop];
}
};
const proxy = new Proxy(target, handler);
// TOM
console.log(proxy.name);  
// 37
console.log(proxy.age);

В данном случае, если обращение идет к свойству name, то есть к свойству, которое хранит строку, то вызываем у этой строки метод toUpperCase() и переводим ее в верхний регистр.

Установка свойства и метод set

Метод set перехватывает обращения к свойству при установке его значения:

const handler = {
set: function(target, property, value, receiver) {
}
};

Метод set имеет четыре параметра:

  • target оригинальный объект, к которому идет проксирование
  • property название свойства, к которому идет обращение
  • value устанавливаемое значение
  • receiver объект Proxy, через который выполняется проксирование

Рассмотрим на примере:

const target = {name: "Tom", age: 37};
const handler = {
set: function(target, prop, value) {
console.log(value);
target[prop] = value;
}
};
const proxy = new Proxy(target, handler);
proxy.name = "Tomas";
// Tomas
console.log(proxy.name);  
proxy.age = 22;      
// 22       
console.log(proxy.age);

В данном примере в методе set сначала логирруем передаваеемое свойству значение, затем устанавливаем свойство:

target[prop] = value;

Немного изменим пример:

const target = {name: "Tom", age: 37};
const handler = {
set: function(target, prop, value) {
if(prop==="age" && value < 1)
console.log("Некорректный возраст");
else
return target[prop] = value;
}
};
const proxy = new Proxy(target, handler);
proxy.name = "Tomas";
// Tomas
console.log(proxy.name);  
// Некорректный возраст
proxy.age = -199;  
// 37
console.log(proxy.age);  
proxy.age = 22;        
// 22     
console.log(proxy.age);

Здесь в методе set обработчика проверяем, если идет установка свойства age и значение меньше 1, то просто выводим сообщение о некорректности данных:

if(prop==="age" && value < 1)
console.log("Некорректный возраст");

Иначе передаем значение свойству оригинального объекта:

else
return target[prop] = value;
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг