代理与反射
//创建代理
const target={
id:'target'
}
const handler = {};
const proxy = new Proxy(target,handler);
//id属性访问同一个值
console.log(target.id);
console.log(proxy.id);
//给代理属性或原始属性赋值,会反映在两个对象上。
// 因为两个对象访问的是同一个值
proxy.id='bar';
console.log(target.id);
console.log(proxy.id)
//Proxy的prototype是undefined因此不能使用instanceof操作符
捕获器参数和反射API
//get()捕获器会接受到目标对象、要查询的属性和代理对象三个参数
const target={
foo:'bar'
};
const handler={
get(trapTarget,property,receiver){
console.log(trapTarget===target);
console.log(property);
console.log(receiver===proxy);
}
}
const proxy = new Proxy(target,handler);
proxy.foo;
代理中的this
在方法中this通常指向调用这个方法的对象。
const target={
thisValEqualsProxy(){
return this===proxy
}
}
const proxy = new Proxy(target,{});
console.log(target.thisValEqualsProxy());//fasle
console.log(proxy.thisValEqualsProxy());//true
如果目标对象依赖于对象标识,可能出现意料之外的问题。
const wm=new WeakMap();
class User{
constructor(userId) {
wm.set(this,userId);
}
set id(userId){
wm.set(this,userId);
}
get id(){
console.log(this===proxy);
return wm.get(this);
}
}
const user = new User(123);
console.log(user.id);//false 123
const proxy = new Proxy(user,{});
console.log(proxy.id)//true undefined
这是因为User实例一开始使用目标对象作为WeakMap的键,代理对象却尝试从自身取得这个实例。要解决这个问题,就需要重新配置代理,把代理User实例改为代理User类本身。之后再创建代理的实例就会以代理实例作为WeakMap的键了。
const UserClassProxy = new Proxy(User,{});
const proxyUser = new UserClassProxy(456);
console.log(proxyUser.id)//false 456
- 本文链接:https://archer-lan.github.io/2023/11/20/JS-%E4%BB%A3%E7%90%86%E4%B8%8E%E5%8F%8D%E5%B0%84/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。