Эта статья одновременно публикуется в личном блоге Github:Прокси серии ES6
предисловие
Несколько дней назад я смоделировал и реализовал две функции MobX —Рукописная реализация наблюдаемых и автозапускаемых методов MobX., который использует Proxy, поэтому я планирую узнать больше о Proxy и сделать заметку.
В том числе предыдущие серии ES6, плюс эта статья должна быть почти серией.
- Разница между сериями ES6 и пусть const и var
- Разрушение назначения переменных в серии ES6
- Полный анализ стрелочных функций серии ES6
- Статья из серии ES6 полностью разбирается в Iterator
- Полный анализ стрелочных функций серии ES6
- Полный анализ генераторов Генераторы серии ES6
- Сборник вопросов-обещаний для серии ES6
- ОБЕЩАНИЕ серии ES6, написанное от руки
Что такое прокси
Proxy对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。 Можно понять, что уровень «перехвата» устанавливается перед целевым объектом, и внешний доступ к объекту должен сначала пройти этот уровень перехвата, поэтому предусмотрен механизм фильтрации и перезаписи внешнего доступа.
const p = new Proxy(target, handler)
Proxy(target, handler)
target
Почему прокси
Прежде чем чему-то научиться, нужно подумать, зачем нам это нужно, на мой взгляд, вообще бывает несколько ситуаций.
- Проксируемый объект не хочет напрямую обращаться
- Управляет и изменяет поведение прикрепленного объекта (вызывающие свойства, назначения имущества, вызовы методов и т. Д.), Включение контроля доступа и повышенной функциональности.
API
Обзор API выглядит следующим образом:
- get(target, propKey, receiver): перехватывает чтение свойств объекта, таких как proxy.foo и proxy['foo'] .
- set(target, propKey, value, receiver): перехватывает настройку свойств объекта, таких как proxy.foo = v или proxy['foo'] = v , возвращает логическое значение.
- has(target, propKey): перехватить операцию propKey в прокси и вернуть логическое значение.
- deleteProperty(target, propKey): перехватить операцию удаления proxy[propKey] и вернуть логическое значение.
- ownKeys(target): Перехват Object.getOwnPropertyNames (прокси), Object.getOwnPropertySymbols (прокси), Object.keys (прокси), for... в цикле возвращает массив. Этот метод возвращает все атрибуты имени самого целевого объекта, а Object.keys() возвращает результат, включающий только сам целевой объект, который может проходить по свойствам.
- getOwnPropertyDescriptor(target, propKey): перехватить Object.getOwnPropertyDescriptor(proxy, propKey) и вернуть объект описания свойства.
- defineProperty(target, propKey, propDesc): Перехват Object.defineProperty(proxy, propKey, propDesc),
- Object.defineProperties(proxy, propDescs), который возвращает логическое значение.
- preventExtensions(target): перехватить Object.preventExtensions(proxy) и вернуть логическое значение.
- getPrototypeOf(target): перехватывать Object.getPrototypeOf(proxy) и возвращать объект.
- isExtensible(target): Interception Object.isExtensible (прокси), возвращает логическое значение.
- setPrototypeOf(target, proto): Obsock.SetPrototepeePeePOF (Proxy, Proto), возвращает логическое значение. Если целевой объект является функцией, то могут быть перехвачены две дополнительные операции.
- apply(target, object, args)
- construct(target, args)
Наиболее распространенный методget
а такжеset
пример
get
const target = {
name: 'jacky',
sex: 'man',
}
const handler = {
get(target, key) {
console.log('获取名字/性别')
return Reflect.get(target, key)
},
}
const proxy = new Proxy(target, handler)
console.log(proxy.name)
Запустить, принтные выходные устройства:
获取名字/性别
jacky
name
get
метод, вget
метод печатает获取名字/性别
, то черезReflect.get(target, key)
Возвращаемое значение получает значение свойства, которое эквивалентноtarget[key]
set
const target = {
name: 'jacky',
sex: 'man',
}
const handler = {
get(target, key) {
console.log('获取名字/性别')
return Reflect.get(target, key)
},
set(target, key, value) {
return Reflect.set(target, key, `强行设置为 ${value}`)
},
}
const proxy = new Proxy(target, handler)
proxy.name = 'monkey'
console.log(proxy.name)
Рабочий вывод:
获取名字/性别
强行设置 monkey
настраиватьproxy.name = 'monkey'
, который должен изменить значение свойства, он вызоветset
Метод, затем значение мы пытаемся изменить настройки обратно для достижения цели перехвата свойств объекта.
Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API。
Reflect.get(target, name, receiver) :查找并返回target对象的name属性,如果没有该属性,则返回undefined。
Reflect.set(target, name, value, receiver) :设置target对象的name属性等于value。
это указывает на
Прокси-сервер изменит this в цели, чтобы указать на, как только прокси-сервер цели, this внутри цели будет указывать на прокси-прокси
const target = new Date('2021-01-03')
const handler = {}
const proxy = new Proxy(target, handler)
console.log(proxy.getDate())
Запустите код, найдете ошибку, подскажитеTypeError: this is not a Date object.
, то есть это не экземпляр объекта Date, и нам нужно вручную привязать исходный объект для его решения:
const target = new Date('2021-01-03')
const handler = {
get(target, prop) {
if (prop === 'getDate') {
return target.getDate.bind(target) // 绑定
}
return Reflect.get(target, prop)
},
}
const proxy = new Proxy(target, handler)
console.log(proxy.getDate()) // 3
Сценарии применения
- Предупреждать или блокировать определенные действия
- Проверка данных.判断数据是否满足条件
так далее...
Ссылаться на
пс:
Если вы считаете, что это хорошо, дайте мне звезду и дайте мне мотивацию продолжать творить!