保存& # 39;这个# 39;javascript原型事件处理程序中的引用

Preserve 'this' reference in javascript prototype event handler

本文关键字:程序 引用 事件处理 javascript 这个 保存 原型      更新时间:2023-09-26

在对象的原型中存储事件处理程序中保存this javascript引用的正确方法是什么?我想远离创建像"_this"或"that"这样的临时变量,我不能使用像jQuery这样的框架。我看到很多人谈论使用bind函数,但不确定如何在我给定的场景中实现它。

var Example = function(foo,bar){
    this.foo = foo;
    this.bar = bar;
};
Example.prototype.SetEvent = function(){
    this.bar.onclick = this.ClickEvent;
};
Example.prototype.ClickEvent = function(){
    console.log(this.foo); // logs undefined because 'this' is really 'this.bar'
};

我发现bind()是迄今为止最干净的解决方案:

this.bar.onclick = this.ClickEvent.bind(this);

顺便说一下,其他 this通常被称为that

查看bind上的MDN文档:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

使用此功能,您可以更改范围(this是什么):

Example.prototype.SetEvent = function(){
    this.bar.onclick = this.ClickEvent.bind(this);
};
但是,请注意,这是EMCA的新添加项,因此可能不支持所有用户代理。在上面链接的MDN文档中有一个polyfill。

bind的问题是只有IE9+支持。

该函数可以用es5-shim填充,但它与本机实现不完全相同:

    注意:绑定函数有一个prototype属性。
  • 警告:绑定函数不会试图阻止你操作它们的argumentscaller属性。
  • 警告:绑定函数在callapply中没有检查,以避免作为构造函数执行。

另一个选项可以是jQuery.proxy:

$(elem).on('click', $.proxy(eventHandler, this));

如果稍后想要删除事件处理程序,这甚至更有帮助,因为当函数经过proxy方法时,jQuery会生成一个新的guid值,然后将该guid应用于核心函数以及由此产生的代理函数,因此您可以使用原始函数引用来解绑定已被代理的事件处理程序回调:

$(elem).off('click', eventHandler);

其他解决方案:使用ES6引入的"箭头函数"。那些具有不改变上下文的特殊性,即this所指出的。下面是一个例子:

function Foo(){
    myeventemitter.addEventListener("mousedown", (()=>{
        return (event)=>{this.myinstancefunction(event)}; /* Return the arrow
function (with the same this) that pass the event to the Foo prototype handler */
    })());
}
Foo.prototype.myinstancefunction = function(event){
    // Handle event in the context of your Object
}

箭头功能规格@ MDN

编辑

小心点。如果您在客户端使用它,并且您不能确定JS解释器的功能,请注意旧的浏览器无法识别箭头函数(请参阅CanIUse统计)。只有当你知道什么会运行它时才使用这个方法(仅限最近的浏览器);NodeJS应用)