В Javascript прокси позволяют перехватывать определенные операции с объектами и настраивать их. Прокси действует как посредник между объектом и «реальным миром». Таким образом, вы можете расширить базовые операции объекта для реализации более сложной логики или переопределить фундаментальные операции в соответствии с вашими потребностями.
Случаи использования включают:
Прокси принимает два параметра:
const target = { greeting1: "Hello", greeting2: "Good morning" } const handler = { get(target, prop, receiver) { return target[prop] " friends!" } } const proxy = new Proxy(target, handler) console.log(proxy.greeting1) // Hello friends! console.log(proxy.greeting2) // Good morning friends!
В этом примере мы определяем прокси. Целевой объект имеет два свойства. Мы определяем обработчик, который обеспечивает реализацию обработчика get(). Ловушка get перехватывает доступ к любому свойству целевого объекта, и внутри нее мы можем изменить поведение по мере необходимости.
При такой настройке это означает, что каждый раз, когда мы собираемся получить доступ к свойствам целевого объекта, обработчик перехватывает его и запускает реализованный нами код. В нашем случае он просто берет значение свойства и добавляет друзей!.
Часто прокси используются с API Reflect. Reflect предоставляет методы с теми же именами, что и ловушки прокси. Как следует из названия, он отражает семантику вызова соответствующих внутренних методов объекта.
const target = { greeting1: "Hello", greeting2: "Good morning" } const handler = { get(target, prop, receiver) { return Reflect.get(...arguments) " friends!" } } const proxy = new Proxy(target, handler) console.log(proxy.greeting1) // Hello friends! console.log(proxy.greeting2) // Good morning friends!
Reflect не требуется для использования прокси, но использование Reflect позволяет нам быть уверенными, что поведение соответствует собственным операциям движка Javascript. Это также обеспечивает совместимость с будущими обновлениями, предотвращает непредвиденные побочные эффекты и упрощает код. Без этого разработчику пришлось бы заново реализовывать такое поведение, как доступ к свойствам, назначение, удаление... что может быть подвержено ошибкам и несовместимо с собственным поведением Javascript.
Давайте создадим несколько примеров, чтобы понять, что мы можем сделать с помощью Proxy.
Предположим, в нашем первом примере мы хотим регистрировать, какие действия выполняются над объектом. Всякий раз, когда мы получаем, устанавливаем или удаляем свойство, я хочу, чтобы оно выводилось на консоль. Это может быть полезно для целей отладки.
const target = { name: "Damien", age: 32, status: "WRITING" } const loggerHandler = { get(target, prop, receiver) { if (prop in target) { console.log(`[LOG] Accessing property ${prop}. Current value is ${target[prop]}`) return Reflect.get(...arguments) } else { console.error(`[LOG] Error accessing non-existent property ${prop}`) } }, set(target, key, value) { console.log(`[LOG] Setting property ${key}. New value: ${value}`) return Reflect.set(...arguments) }, deleteProperty(target, prop) { console.warn(`[LOG] Deleting property: ${prop}`) return Reflect.deleteProperty(...arguments) } } const proxy = new Proxy(target, loggerHandler) proxy.name // [LOG] Accessing property name. Current value is Damien proxy.status // [LOG] Accessing property status. Current value is WRITING proxy.name = "Bob" // [LOG] Setting property name. New value: Bob proxy.status = "NAPPING" // [LOG] Setting property status. New value: NAPPING proxy.job = "Developer" // [LOG] Setting property job. New value: Developer delete proxy.job // [LOG] Deleting property: job proxy.job // [LOG] Error accessing non-existent property job
Мы определили loggerHandler, который переопределяет три основные операции: получение, установку и удаление. Для каждого действия мы записываем в консоль что-то, описывающее происходящее. Прелесть прокси в том, что нам не нужно каждый раз писать оператор консоли. Мы взаимодействуем с нашим объектом, как всегда, а прокси-сервер заботится о поведении журнала. Довольно круто, нет?
Во втором примере мы будем использовать прокси для проверки ввода данных формы.
const validationRules = { name: value => value.length >= 3 || "Name must be at least 3 characters long", age: value => Number.isInteger(value) || "Age must be a number", email: value => value.includes('@') || "Enter a valid email" } let formData = { name: "", age: null, email: "" } const formHandler = { set(target, key, value) { if (typeof value === "string") { value = value.trim() } const validationResult = validationRules[key](value) if (validationResult !== true) { console.error(`Validation failed for property ${key}: ${validationResult}`) return false; } return Reflect.set(...arguments) } } const formProxy = new Proxy(formData, formHandler) formProxy.age = "32 years old" // Validation failed for property age: Age must be a number formProxy.name = "Da" // Validation failed for property name: Name must be at least 3 characters long formProxy.email = "damcoss mail.com" // Validation failed for property email: Enter a valid email formProxy.age = 32 // OK formProxy.name = "Damien" // OK formProxy.email = "[email protected]" // OK
Здесь мы определяем объект с различными методами, используемыми для проверки допустимости значений. Затем мы используем ту же логику. У нас есть целевой объект formData, который мы хотим проксировать. В formHandler мы переопределяем метод set() для применения наших правил проверки к входным значениям.
Прокси в сочетании с API Reflect представляют собой гибкие и мощные инструменты для перехвата и настройки операций с объектами. Используя их, вы можете динамически улучшать и контролировать поведение. Используя API Reflect, вы также убедитесь, что поведение соответствует движку Javascript.
Прокси часто используются в библиотеках и платформах для обеспечения расширенного поведения, такого как реактивное программирование, оболочки API и наблюдение за свойствами.
Удачи ❤️
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3