当前位置: 代码迷 >> 综合 >> Proxy的理解
  详细解决方案

Proxy的理解

热度:27   发布时间:2024-01-28 06:17:39.0

Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。

接收两个参数:被代理者和处理代理的对象

Proxy称为代理,当通过代理来操作被代理者时,会触发代理相关的代码;如果直接操作被代理者,不会触发代理相关代码。

const handler = {get(target, prop, receiver){console.log(target); 被代理者obj对象 {name: "zhu", age: 24}console.log(prop);   被代理者的属性名 nameconsole.log(receiver);  Proxy或者继承Proxy的对象   Proxy {name: "zhu", age: 24}return "proxy调用了该方法"}
}
let obj = {name: "zhu",age: 24
}
let proxy = new Proxy(obj, handler);
console.log(obj.name);  打印zhu,无法触发代理代码
console.log(proxy.name); 打印 proxy调用了该方法,触发代理代码中赋值相关的代码
console.log(proxy);       Proxy {name: "zhu", age: 24}

(1)handler.get() 方法用于代理处理对象读取属性的操作。

以下是传递给get方法的参数,this上下文绑定在handler对象上.

  • target 目标对象。
  • property 被获取的属性名。
  • receiver   Proxy或者继承Proxy的对象。

返回值:get方法可以返回任何值。

该方法会处理目标对象的以下操作:

  • 访问属性: proxy[foo]和 proxy.bar
  • 访问原型链上的属性: Object.create(proxy)[foo]
  • Reflect.get()
const handler = {get(target, prop, receiver){console.log(target);    被代理者obj对象 {name: "zhu", age: 24}console.log(prop);      被代理者的属性名 nameconsole.log(receiver);  Proxy或者继承Proxy的对象   Proxy {name: "zhu", age: 24}return target[prop];}
}
let obj = {name: "zhu",age: 24
}
let proxy = new Proxy(obj, handler);
console.log(proxy.name);   get方法的返回值:zhu

如果违背了以下的约束,proxy会抛出 TypeError:

  • 如果要访问的目标属性是不可写以及不可配置的,则返回的值必须与该目标属性的值相同。
  • 如果要访问的目标属性没有配置访问方法,即get方法是undefined的,则返回值必须为undefined。

关于第一条的异常:只有当configurable和writable同时为false的时候,get方法的返回值不能修改该属性的值,不然会报错。

var obj = {};
Object.defineProperty(obj, "a", { configurable: false, enumerable: false, value: 10, writable: false 
});var p = new Proxy(obj, {get: function(target, prop) {return 20;}
});
console.log(p.a);    会抛出TypeError

(2)handler.set() 方法用于代理处理对象设置属性值的操作。

以下是传递给 set() 方法的参数。this 绑定在 handler 对象上。

target 目标对象。

property 将被设置的属性名或 Symbol。

value 新属性值。

receiver  最初被调用的对象。通常是 proxy 本身,但 handler 的 set 方法也有可能在原型链上,或以其他方式被间接地调用(因此不一定是 proxy 本身)。

比如:假设有一段代码执行 obj.name = "jen", obj 不是一个 proxy,且自身不含 name 属性,但是它的原型链上有一个 proxy,那么,那个 proxy 的 set() 处理器会被调用,而此时,obj 会作为 receiver 参数传进来。

const handler = {set(target, prop, value, receiver) {console.log(this);   handler对象console.log(target); 目标对象   {name: "zhu", age: 24}console.log(prop);   将被设置的属性名或 Symbol  nameconsole.log(value);  设置的属性值   zhuyuzhuconsole.log(receiver); 最初被调用的对象  Proxy {name: "zhu", age: 24}}
}
let obj = {name: "zhu",age: 24
}
let proxy = new Proxy(obj, handler);
proxy.name = "zhuyuzhu";

 

  相关解决方案