JavaScript - Прокси: Пособие для начинающих
Здравствуйте,野心勃勃的程序设计师们! Сегодня мы отправимся в увлекательное путешествие в мир JavaScript Прокси. Не волнуйтесь, если вы никогда о них не слышали - мы начнем с самых азов и будем двигаться вверх. К концу этого руководства вы будете хорошо разбираться в искусстве использования Прокси, как профессионал!
Что такое Прокси в JavaScript?
Давайте начнем с простой аналогии. Представьте, что вы знаменитость (ведь почему бы не мечтать масштабно, правда?). Вы так有名, что вам нужно, чтобы кто-то управлял вашими встречами, fan mail и другими повседневными делами. Этот человек, действующий от вашего лица, называется прокси в реальном мире.
В JavaScript, Прокси работает аналогичным образом. Это объект, который обертывает другой объект (давайте назовем его целевым объектом) и может перехватывать и переопределять основные операции для этого объекта. Круто, правда?
Вот базовый пример, чтобы мы могли начать:
let target = {
name: "John Doe",
age: 30
};
let handler = {
get: function(target, property) {
console.log(`Получение свойства ${property}`);
return target[property];
}
};
let proxy = new Proxy(target, handler);
console.log(proxy.name);
Если вы запустите этот код, вы увидите:
Получение свойства name
John Doe
Давайте разберем это:
- У нас есть
target
объект с свойствамиname
иage
. - Мы создаем
handler
объект сget
трепом (мы поговорим подробнее о трепах скоро). - Мы создаем
proxy
используяProxy
конструктор, передавая нашtarget
иhandler
. - Когда мы пытаемся получить
proxy.name
, нашget
треп срабатывает, логируя сообщение перед тем, как вернуть фактическое значение.
JavaScript Proxy Handlers
Теперь, когда мы обсушили ноги, давайте погрузимся немного глубже в Proxy handlers. Handler - это объект, который определяет трепы для нашего Прокси. Трепы - это методы, которые предоставляют доступ к свойствам, assignment,枚举, вызов функции и т.д.
Вот таблица некоторых.common handler трепов:
Треп | Описание |
---|---|
get | Перехватывает доступ к свойствам |
set | Перехватывает assignment свойств |
has | Перехватывает in оператор |
deleteProperty | Перехватывает delete оператор |
apply | Перехватывает вызовы функций |
construct | Перехватывает new оператор |
Давайте посмотрим на более comprehensive пример, используя несколько трепов:
let target = {
name: "Alice",
age: 25
};
let handler = {
get: function(target, property) {
console.log(`Доступ к свойству ${property}`);
return target[property];
},
set: function(target, property, value) {
console.log(`Установка свойства ${property} в ${value}`);
target[property] = value;
return true;
},
has: function(target, property) {
console.log(`Проверка существования ${property}`);
return property in target;
}
};
let proxy = new Proxy(target, handler);
console.log(proxy.name); // Запускает get треп
proxy.job = "Developer"; // Запускает set треп
console.log("age" in proxy); // Запускает has треп
Запуск этого кода выведет:
Доступ к свойству name
Alice
Установка свойства job в Developer
Проверка существования age
true
Не правда ли, это здорово? Наш Прокси теперь перехватывает доступ к свойствам, assignment и in
оператор!
Применение Proxy Объекта в JavaScript
Вы можете задаться вопросом: "Это cool и все, но когда я действительно буду использовать это?" Great question! Прокси имеют несколько praktical применений:
- Валидация: Вы можете использовать Прокси для валидации данных перед их установкой в объект.
let user = {
name: "Bob",
age: 30
};
let validator = {
set: function(obj, prop, value) {
if (prop === "age") {
if (typeof value !== "number") {
throw new TypeError("Age must be a number");
}
if (value < 0 || value > 120) {
throw new RangeError("Age must be between 0 and 120");
}
}
obj[prop] = value;
return true;
}
};
let proxiedUser = new Proxy(user, validator);
proxiedUser.age = 25; // Это работает
try {
proxiedUser.age = "thirty"; // Это выбрасывает TypeError
} catch (e) {
console.log(e.message);
}
try {
proxiedUser.age = 150; // Это выбрасывает RangeError
} catch (e) {
console.log(e.message);
}
- Логирование: Вы можете использовать Прокси для логирования доступа к свойствам объекта.
let target = {
name: "Charlie",
age: 35
};
let logger = {
get: function(target, property) {
console.log(`Свойство ${property} было доступно в ${new Date()}`);
return target[property];
}
};
let proxiedTarget = new Proxy(target, logger);
console.log(proxiedTarget.name);
console.log(proxiedTarget.age);
- Значения по умолчанию: Вы можете использовать Прокси для предоставления значений по умолчанию для несуществующих свойств.
let handler = {
get: function(target, property) {
return property in target ? target[property] : "Property not found";
}
};
let proxy = new Proxy({}, handler);
proxy.name = "David";
console.log(proxy.name); // Выводит: David
console.log(proxy.age); // Выводит: Property not found
Список JavaScript Proxy Handlers
Чтобы подвести итог нашеему путешествию в мир JavaScript Прокси, давайте посмотрим на comprehensive список всех доступных handler трепов:
Handler Trap | Description |
---|---|
get | Перехватывает получение значений свойств |
set | Перехватывает установку значений свойств |
has | Перехватывает in оператор |
deleteProperty | Перехватывает delete оператор |
apply | Перехватывает вызовы функций |
construct | Перехватывает new оператор |
getPrototypeOf | Перехватывает Object.getPrototypeOf
|
setPrototypeOf | Перехватывает Object.setPrototypeOf
|
isExtensible | Перехватывает Object.isExtensible
|
preventExtensions | Перехватывает Object.preventExtensions
|
getOwnPropertyDescriptor | Перехватывает Object.getOwnPropertyDescriptor
|
defineProperty | Перехватывает Object.defineProperty
|
ownKeys | Перехватывает Object.getOwnPropertyNames и Object.getOwnPropertySymbols
|
И вот и все! Мы рассмотрели основы JavaScript Прокси,探讨了 некоторые praktical применения и даже посмотрели на все доступные handler трепы. Помните, как и любое мощное средство, Прокси должны использоваться с умом. Они великолепны для某些 применений, но они также несут с собой performance overhead.
Надеюсь, это руководство было полезным для вас в demystifying JavaScript Прокси. Продолжайте практиковаться, продолжайте программировать, и вы станете профи в прокси! Счастливого кодирования!
Credits: Image by storyset