记录 getter 使用代理获取的内容
Log what getter gets using proxy
我有以下记录获取事件的代理处理程序。
const proxyHandler = {
get: function(target, prop) {
console.log("get", prop);
return Reflect.get(target, prop);
}
};
const obj = new Proxy(
{
value: 4,
text: "hi",
get textVal() {
return this.text.repeat(this.value);
},
getTextVal() {
return this.text.repeat(this.value);
}
},
proxyHandler
);
console.log("------- normal func -------")
console.log(obj.getTextVal());
console.log("------- getter func -------")
console.log(obj.textVal);
当我登录 console.log(obj.getTextVal())
时,我得到:
get getTextVal
get text
get value
hihihihi
但是当我登录 getter console.log(obj.textVal)
时,我只得到以下信息:
get textVal
hihihihi
如何让 obj.textVal
记录 get text
并使用代理获取 get value
事件? IE。当 运行 console.log(obj.textVal)
我想要下面的结果。
get getTextVal
get text
get value
hihihihi
您可以将 Proxy
实例设置为 proxyHandler
对象并通过它访问属性(而不是 this
)。
const proxyHandler = {
get: function(target, prop) {
console.log("get", prop);
return Reflect.get(target, prop);
}
};
const proxifiedObj = {
value: 4,
text: "hi",
get textVal() {
return this.proxyInstance.text.repeat(this.proxyInstance.value);
},
getTextVal() {
return this.text.repeat(this.value);
}
}
obj = proxifiedObj.proxyInstance = new Proxy(proxifiedObj, proxyHandler);
console.log("------- normal func -------")
console.log(obj.getTextVal());
console.log("------- getter func -------")
console.log(obj.textVal);
console.log(obj.textVal);
get getTextVal
get text
get value
hihihihi
更新:
或者您可以通过创建自定义 Proxy
来为您完成作业来做同样的事情
(注意:Proxy
class 不能扩展,但我们可以使用 模式):
class InstanceAwareProxy {
constructor(proxifiedObject, proxyHandler) {
return proxifiedObject.proxyInstance
= new Proxy(proxifiedObject, proxyHandler);
}
}
obj = new InstanceAwareProxy(proxifiedObj, proxyHandler);
以上答案有效,但还有更优雅的解决方案。您在 Proxy 陷阱和 Reflect 参数中缺少 receiver
。只需将代理更改为:
const proxyHandler = {
get: function(target, prop, receiver) {
console.log("get", prop);
return Reflect.get(target, prop, receiver);
}
};
Notice the new receiver
in the trap and Reflect arguments.
代理陷阱 target
和 receiver
之间有一个重要区别。在这种情况下,target
是底层原始对象,而 receiver
是代理包装器。如果您不将 receiver
传递给 Reflect 调用,get
操作中的所有内容都将 运行 针对原始对象,并且不会触发代理陷阱。
如果你有时间我建议你阅读 ES6 规范的相关部分以完全掌握这两者之间的区别。否则,只要确保将 all 代理陷阱参数转发给匹配的 Reflect 调用(如果您的目标是透明包装)。
我有以下记录获取事件的代理处理程序。
const proxyHandler = {
get: function(target, prop) {
console.log("get", prop);
return Reflect.get(target, prop);
}
};
const obj = new Proxy(
{
value: 4,
text: "hi",
get textVal() {
return this.text.repeat(this.value);
},
getTextVal() {
return this.text.repeat(this.value);
}
},
proxyHandler
);
console.log("------- normal func -------")
console.log(obj.getTextVal());
console.log("------- getter func -------")
console.log(obj.textVal);
当我登录 console.log(obj.getTextVal())
时,我得到:
get getTextVal
get text
get value
hihihihi
但是当我登录 getter console.log(obj.textVal)
时,我只得到以下信息:
get textVal
hihihihi
如何让 obj.textVal
记录 get text
并使用代理获取 get value
事件? IE。当 运行 console.log(obj.textVal)
我想要下面的结果。
get getTextVal
get text
get value
hihihihi
您可以将 Proxy
实例设置为 proxyHandler
对象并通过它访问属性(而不是 this
)。
const proxyHandler = {
get: function(target, prop) {
console.log("get", prop);
return Reflect.get(target, prop);
}
};
const proxifiedObj = {
value: 4,
text: "hi",
get textVal() {
return this.proxyInstance.text.repeat(this.proxyInstance.value);
},
getTextVal() {
return this.text.repeat(this.value);
}
}
obj = proxifiedObj.proxyInstance = new Proxy(proxifiedObj, proxyHandler);
console.log("------- normal func -------")
console.log(obj.getTextVal());
console.log("------- getter func -------")
console.log(obj.textVal);
console.log(obj.textVal);
get getTextVal
get text
get value
hihihihi
更新:
或者您可以通过创建自定义 Proxy
来为您完成作业来做同样的事情
(注意:Proxy
class 不能扩展,但我们可以使用
class InstanceAwareProxy {
constructor(proxifiedObject, proxyHandler) {
return proxifiedObject.proxyInstance
= new Proxy(proxifiedObject, proxyHandler);
}
}
obj = new InstanceAwareProxy(proxifiedObj, proxyHandler);
以上答案有效,但还有更优雅的解决方案。您在 Proxy 陷阱和 Reflect 参数中缺少 receiver
。只需将代理更改为:
const proxyHandler = {
get: function(target, prop, receiver) {
console.log("get", prop);
return Reflect.get(target, prop, receiver);
}
};
Notice the new
receiver
in the trap and Reflect arguments.
代理陷阱 target
和 receiver
之间有一个重要区别。在这种情况下,target
是底层原始对象,而 receiver
是代理包装器。如果您不将 receiver
传递给 Reflect 调用,get
操作中的所有内容都将 运行 针对原始对象,并且不会触发代理陷阱。
如果你有时间我建议你阅读 ES6 规范的相关部分以完全掌握这两者之间的区别。否则,只要确保将 all 代理陷阱参数转发给匹配的 Reflect 调用(如果您的目标是透明包装)。