Day 9
Прокси и отражение
Основы агентства:
- Прокси является абстракцией целевого объекта и может использоваться в качестве замены для целевого объекта, но он полностью независим от целевого объекта Целевым объектом можно манипулировать напрямую или через прокси.
Создайте пустой прокси:
-
Самый простой прокси — это пустой прокси, а это значит, что он ничего не делает, кроме как действует как абстрактный целевой объект.Все операции, выполняемые над прокси-объектом, будут без проблем распространяться на целевой объект.Поэтому везде, где используется целевой объект, он Связанный с ним прокси-объект можно использовать таким же образом.
Пример 1:
const target = { id: 'target' };
const handler = {};
const proxy = new Proxy(target, handler);
// id属性会访问同一个值
console.log(target.id); // target
console.log(proxy.id); // target
// 给目标属性赋值会反映在两个对象上, 因为两个对象访问的是同一个值
target.id = 'foo';
console.log(target.id); // foo
console.log(proxy.id); // foo
// 给代理属性赋值会反映在两个对象上,因为这个赋值会转移到目标对象
proxy.id = 'bar';
console.log(target.id); // bar
console.log(proxy.id); // bar
// hasOwnProperty()方法在两个地方 都会应用到目标对象
console.log(target.hasOwnProperty('id')); // true
console.log(proxy.hasOwnProperty('id')); // true
Резюме: Это простейший случай пустого прокси.Может быть непонятно на первый взгляд.Поэтому я сначала растерялся,но не волнуйтесь,теперь нужно просто понять и знать,что делает прокси.В этом примере , Цель — цель прокси, прокси — это прокси, цель прокси — общая с атрибутом прокси, операция — общая, включая метод, но прокси не равен цели прокси. более склонен к работе прокси, прокси перенаправляет операцию прокси.Цель, а затем оперировать, то, что есть у цели, будет принадлежать агенту, а то, что есть у агента, будет передано цели соответственно;
Ловец кода и метод отражения:
-
используя прокси"Цель": можно определить"ловец"(ловушка), ловушка может быть вызвана прямо или косвенно на прокси-объекте.Каждый раз, когда эти основные операции вызываются на прокси-объекте, прокси-сервер может вызывать функцию-ловушку до того, как эти операции будут распространены на целевой объект, тем самым перехватывая и изменяя соответствующее поведение.
- С точки зрения непрофессионала, ловушка выполняется первой при вызове прокси-объекта, тем самым перехватывая и изменяя соответствующее поведение, что похоже на добавление слоя условного суждения или всплывающего подтверждения.
-
"handler": Объект обработки прокси. В примере 1 это пустой объект. В большинстве случаев это не пустой объект, но определена одна или несколько ловушек для обработки прокси. Если он не определен, он будет так же, как пустой объект в приведенном выше примере.Как и объекты, используйте поведение по умолчанию.
-
"set trap": обычно используемая ловушка, условие запуска срабатывает, когда установлено значение атрибута,
-
"Reflect.set": функция, которая присваивает значение свойству. вернуть
Boolean, если обновление прошло успешно, вернутьtrueПервая набор ловушки принимает 4 параметра,
-
trapTarget - объект полученного атрибута, являющийся целью **прокси**
-
key - свойство для записи"ключ"
-
value - свойство для записи"стоимость"
-
приемник - объект для работы, обычно"играет роль"
Пример 2. Используйте set trap, чтобы убедиться, что значением свойства является число
-
let target = {
name: "target"
};
let proxy = new Proxy(target, {
//target,name,target,proxy;
set(trapTarget, key, value, receiver) {
console.log(`trapTarget is ${trapTarget}, key is ${key}, value is ${value}, receiver is ${receiver}`)
// 忽视存在的属性,以免产生影响,不存在的属性才会进入判断
if (!trapTarget.hasOwnProperty(key)) {
//判断值是否为number
if (isNaN(value)) {
throw new TypeError("Property must be a number.");
}
}
// 添加到属性
return Reflect.set(trapTarget, key, value, receiver);
}
});
// 添加一个新的属性
proxy.count = 1;
console.log(proxy.count); // 1
console.log(target.count); // 1
// 赋值给存在target上的属性
proxy.name = "proxy";
console.log(proxy.name); // "proxy"
console.log(target.name); // "proxy"
// 新的属性值不是数字会抛出异常
proxy.anotherName = "proxy";
小结:这个例子打印出了4个参数的时刻变化,可以清晰的看到参数对应的值,可以发现,每次设置属性值的时候都会进行拦截判断,所以在获取时候,可以用get进行拦截判断,
-
"get trap":
-
get — это ловушка, используемая при чтении свойств объекта, она принимает 3 параметра.
-
trapTarget: Считанное свойство, из которого объект является целью
-
key- читатьkey -
receiver- Объект операции, обычно проксиПример 1: Это обоснование использования обычного прокси-сервера
-
const handler = {
get: function(obj, prop) {
return prop in obj ? obj[prop] : 37;
}
};
const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37
小结:p.a的时候,获取代理里面a的值经过get,返回了 a的值,p.b一样,然后c in p,因为p没有c这个属性,所以会返回false,p.c像p获取c属性,进入get,赋值为37,
-
Давайте посмотрим на исчерпывающий пример set and get
Пример 3;
var p = {
name:"chen",
work:function() {
console.log("wording...");
},
_age:18,
//监听获取name属性的事件
get name(){
return this._age;
},
//监听设置age属性的事件
set age(val) {
if (val<0 || val> 100) {//如果年龄大于100就抛出错误
throw new Error("invalid value")
}else{
this._age = val;
}
}
};
console.log(p.name);//输出18,因为这里触发了监听name属性的拦截,所以返回的age,
console.log(p._age);//这里的age没有获取拦截,所以输出原值
console.log(p._age =20);//输出20,因为这里进入设置拦截,满足条件,完成赋值
console.log(p._age =200);//报错,设置拦截进入,不满足条件,报错
console.log(p.name = 'yu')//输出 yu,因为name没有设置拦截,所以可以成功
Резюме: Прочитав это, я полагаю, что все понимают базовые знания об агенте и его принципах.На самом деле, есть много ловцов, таких как has и т. д., но основной принцип тот же, пока вы понимаете, что параметры представляют, условия триггера ловушки, проблема может быть решена легко, я надеюсь, что это может помочь всем
В этой статье используетсяmdniceнабор текста