Прокси в JS
В этой статье вы узнаете, что такое прокси и как их используют в JavaScript.
Прокси позволяют оборачивать объекты и переопределять такие операции в объекте, как чтение, вставка, валидация и так далее. То есть прокси-объекты позволяют добавить функции или объекту особое поведение, заданное пользователем — это называется метапрограммированием.
Создание прокси
Синтаксис
new Proxy(цель, обработчик)
new Proxy()
— конструктор прокси.цель
— исходный объект, который виртуализируется прокси. Он часто используется в качестве источника данных в прокси.обработчик
— объект-заменитель, который переопределяет поведение исходного объекта.
Пример
let student1 = {
age: 24,
name: "Андрей"
}
const handler = {
get: function(obj, prop) {
return obj[prop] ? obj[prop] : 'Такого свойства нет'
}
}
const proxy = new Proxy(student1, handler);
console.log(proxy.name); // Вывод: Андрей
console.log(proxy.age); // Вывод: 24
console.log(proxy.class); // Вывод: Такого свойства нет
Мы использовали метод get()
для доступа к значению свойства объекта. Если свойство недоступно в объекте, мы сообщаем пользователю: Такого свойства нет.
Как вы видите, прокси можно использовать для создания новых операций для объекта. Например, если потребуется проверить, есть ли у объекта определенный ключ и выполнить действие на основе этого ключа, вам поможет прокси.
Передать в конструктор прокси можно и пустой обработчик. В таком случае прокси будет вести себя как оригинальный объект. Например:
let student = {
name: 'Андрей',
age: 24
}
const handler = { };
// передаем пустой обработчик
const proxy1 = new Proxy(student, {});
console.log(proxy1); // Вывод: Proxy {name: "Андрей", age: 24}
console.log(proxy1.name); // Вывод: Андрей
Методы обработчика прокси
В JavaScript встроены два метода для обработчика прокси: get()
и set()
.
Обработчик get()
Метод get()
используется для доступа к свойствам целевого объекта (цель
). Например:
let student = {
name: 'Андрей',
age: 24
}
const handler = {
// получаем ключ и значение объекта
get(obj, prop) {
return obj[prop];
}
}
const proxy = new Proxy(student, handler);
console.log(proxy.name); // Вывод: Андрей
Как вы видите, метод get()
принимает в качестве параметров объект и свойство.
Обработчик set()
Метод set() используется для установки значения объекта. Например:
let student = {
name: 'Андрей'
}
let setNewValue = {
set: function(obj, prop, value) {
obj[prop] = value;
return;
}
};
// задаем новый прокси
let person = new Proxy(student, setNewValue);
// задаем новую пару ключ/значение
person.age = 25;
console.log(person); // Вывод: Proxy {name: "Андрей", age: 25}
Как вы видите, с помощью обработчика set()
мы добавили к объекту student
новое свойство age
.
Использование прокси
1. Для валидации
Прокси можно использовать для валидации. Это значит, что вы можете проверить значение ключа и выполнить действие на его основе.
Например, так:
let student = {
name: 'Андрей',
age: 24
}
const handler = {
// получаем ключ и значение объекта
get(obj, prop) {
// проверяем условие
if (prop == 'name') {
return obj[prop];
} else {
return 'Запрещено';
}
}
}
const proxy = new Proxy(student, handler);
console.log(proxy.name); // Вывод: Андрей
console.log(proxy.age); // Вывод: Запрещено
В этом примере мы сделали доступным только свойство name
в объекте student
. Если попытаться получить значение другого свойства, вернется сообщение: Запрещено.
2. Объект только для чтения
Бывают ситуации, когда вам нужно запретить вносить изменения в объект. В таких случаях вы можете использовать прокси, чтобы сделать объект доступным только для чтения. Например, так:
let student = {
name: 'Андрей',
age: 23
}
const handler = {
set: function (obj, prop, value) {
if (obj[prop]) {
// нельзя изменять значения объекта student
console.log('Только для чтения')
}
}
};
const proxy = new Proxy(student, handler);
proxy.name = 'Сергей'; // Вывод: Только для чтения
proxy.age = 33; // Вывод: Только для чтения
В приведенной выше программе объект изменить никак не получится.
Если попытаться изменить объект, выведется сообщение: Только для чтения.
3. Вызов функции при выполнении условия
Прокси можно использовать для вызова какой-то другой функции при выполнении определенного условия. Например:
const myFunction = () => {
console.log("Выполняется функция myFunction")
};
const handler = {
set: function (target, prop, value) {
if (prop === 'name' && value === 'Андрей') {
// вызываем другую функцию
myFunction();
}
else {
console.log('Доступно только поле name');
}
}
};
const proxy = new Proxy({}, handler);
proxy.name = 'Андрей'; // Вывод: Выполняется функция myFunction
proxy.age = 33; // Вывод: Доступно только поле name