如何将 this 上下文传递给事件处理程序?

Posted

技术标签:

【中文标题】如何将 this 上下文传递给事件处理程序?【英文标题】:How do I pass the this context into an event handler? 【发布时间】:2011-07-26 07:34:53 【问题描述】:

我知道这个问题没有多大意义,但让我试着澄清一下。

我有一个类,叫做 ScrollBanner,它看起来有点如下(为简洁起见,省略了很多):

function ScrollBanner() 
    this.initialize = function(selector) 
        $('span#banner1-nav').click(this._onClickNavigation);
    

    this._onClickNavigation = function(event) 
        this.restartTimer(); // this == span#banner1-nav element from this.initialize
        //...
    

    this.restartTimer() 
        //...
    

如您所见,this.initialize 将点击处理程序设置为 this._onClickNavigation。有些人可能希望事件处理程序中的 this 引用 ScrollBanner 实例,但遗憾的是它没有。它指的是触发点击事件的元素,在本例中为 span#banner1-nav

this 引用 ScrollBanner 类实例的最佳方法是什么?

【问题讨论】:

【参考方案1】:

旧的/传统的方式:

在变量中捕获this

this.initialize = function(selector) 
    var that = this;
    $('span#banner1-nav').click(function(event) 
       that._onClickNavigation(event);
    );

您还可以将 this 分配给变量,例如instance:

function ScrollBanner() 
    var instance = this;
    // ...

并在所有调用中引用instance 而不是this

总体思路是将this存储在更高范围的变量中。


ECMAScript5 方式:

ECMAScript5 引入了一个新的函数属性:.bind()。 MDC's documentation 显示了不支持它的浏览器的实现。有了它,您可以将某个上下文绑定到一个函数:

this.initialize = function(selector) 
    $('span#banner1-nav').click(this._onClickNavigation.bind(this));

但在幕后它正在做同样的事情。优点是您可以使用支持的浏览器中的内置功能。

请注意,这与 applycall 不同。这两者都设置了上下文执行函数,而bind 只设置上下文而不执行函数。


jQuery方式:

jQuery 提供了一个方法$.proxy() 做同样的事情:

$('span#banner1-nav').click($.proxy(this._onClickNavigation, this));

【讨论】:

好电话,我通常习惯在我的构造函数顶部分配一个var that = this,所以你总是可以参考它。然后一直使用that,以免混淆(当然假设你引用的是那个,而不是其他的) 这很有用,但感觉很脏。 :) @JoeZephyr:就是这样 ;) 请也看看我的更新。 jQuery 没有跨浏览器兼容的 bind() 函数吗? @JoeZephyr:对,我忘了。 jQuer 有$.proxy:api.jquery.com/jQuery.proxy 至少你现在知道所有可能的方法了;)【参考方案2】:

我知道这是一个老问题,但我看到,在 cmets 中,提到了 $.proxy()。是的,它确实会更改对象的上下文,但不会更改 jQuery 事件。

 $('.selector').click( $.proxy( function() 
     console.log(this); /* this is set to .selector */
 , this));

$.proxy() 返回this 引用的范围内的函数,但随后该函数被click() 返回并使用,然后将范围更改为.selector 元素。

我在一分钟前测试过,如果我弄错了,请告诉

【讨论】:

不确定这在旧 jQuery 版本中是否有所不同,但这个例子表明你错了:jsfiddle.net/mazztgc9。

以上是关于如何将 this 上下文传递给事件处理程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义参数传递给事件处理程序

如何将事件和其他参数传递给单击处理程序

将额外参数传递给事件处理程序?

ReactJS V16如何将父函数传递给孙事件处理程序[重复]

将函数传递给 jquery On 事件处理程序

将多个参数传递给 React 中的事件处理程序