javascript - 代理事件目标上的 addEventListener

标签 javascript proxy javascript-objects dom-events addeventlistener

我正在尝试创建一个基本上既是 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 监听)又可以是值的存储(代理对象负责修改时调度事件)。到目前为止,此方法仅在您随身携带两者 targetstate 时才有效...

知道为什么我不能通过 Proxy 调用 addEventListener 吗?


从技术上讲,调用 state.addEventListener() 会通过 get 原型(prototype)方法,所以我尝试在代理处理程序,但它没有添加任何内容......(即使它确实达到了,因为我也尝试在那里添加一个 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/

相关文章:

javascript - 将变量传递给 html 标记中的 javascript 函数

javascript - 将语言声明提取到 JavaScript 变量中

c# - 如何使我的 WCF 服务调用通过已配置的本地代理服务器?

javascript - 从哪个版本开始,IE 可以支持 Object.create(null)?

javascript - TS/JS 从正则表达式匹配中分割字符串的一部分

javascript - 如果 URL 包含字符串然后运行 ​​jQuery 函数?

proxy - haproxy/docker 未找到启用的监听器(检查 'bind' 指令)!退出

Git代理失败需要帮助

javascript - 设置对象属性(其中对象可能为 null 或未定义)的更简洁方法

javascript - 如何在 JavaScript 中转换文档数组中的字典?