我正在尝试创建一个基本上都是 Proxy
的对象和 EventTarget
.目标是能够订阅对此对象所做的任何更改。
这是我定义这个对象的方式:
const target = new EventTarget()
const state = new Proxy(target, {
set: (obj, key, value) => {
Reflect.set(obj, key, value)
obj.dispatchEvent(new CustomEvent('change', {detail: {key, value}}))
},
deleteProperty: (obj, key) => {
Reflect.deleteProperty(obj, key)
obj.dispatchEvent(new CustomEvent('change', {detail: {key, value: undefined}}))
}
})
在这一点上,我希望能够调用
state.addEventListener('change', console.log)
但这给了我一个错误:Uncaught TypeError: Illegal invocation
所以这是有效的:
target.addEventListener('change', console.log)
state.foo = 'bar'
// logs the event
但正如我所说,我希望有一个单一的统一对象,它既可以是目标(可以用
addEventListener
收听),也可以是值的存储(代理对象在修改时负责调度事件)。到目前为止,此方法仅在您随身携带 时才有效。两个 target
和 state
...知道为什么我不能调用
addEventListener
通过Proxy
?从技术上讲,请调用
state.addEventListener()
通过get
原型(prototype)方法,所以我尝试定义get: Reflect.get
在代理处理程序中,但它没有添加任何内容......(即使它确实达到了,因为我也尝试在那里添加 console.log
)那为什么我不能调用
addEventListener
通过代理,但它直接在 target
上工作正常目的?
最佳答案
由于您使用的是代理,因此您确实需要像您想的那样使用 getter,但您很可能没有绑定(bind)该函数,因此它将使用正确的 this
调用它。 .当您在没有它的情况下返回该函数时失去该连接,它将改为引用代理对象,该代理对象本身并未实现 EventTarget/EventListener 方法。
let target = document.documentElement;
let targetProxy = new Proxy(target,{
get:(obj,key)=>{
let value = Reflect.get(obj,key);
if(typeof(value) == "function"){
return value.bind(obj);
}
return value;
}
});
targetProxy.addEventListener('click',()=>console.log('clicked'));
关于javascript - 代理事件目标上的 addEventListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59109571/