如何将此上下文传递给事件处理函数?

问题描述:

我知道这个问题没有多大意义,但让我试着澄清一下。如何将此上下文传递给事件处理函数?

我有一个类,叫做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设置一个单击处理程序这一点。 _onClickNavigation。有些人可能会期望这个里面的事件处理程序引用ScrollBanner实例,但遗憾的是它没有。它指的是trigerred click事件,在这种情况下跨度#banner1-NAV

会是怎样的最好的方式得到这个来指代ScrollBanner类实例的元素?

旧的/传统的方式:

捕捉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)); 
+0

良好的通话,我一般做分配'VAR是= this'我构造的顶部,这样的习惯你总是有一个参考。然后一直使用'that',这样就不会产生混淆(当然假定你引用了这个,而不是其他的) – brad 2011-03-30 18:30:21

+2

这很有用,但是感觉很脏。 :) – 2011-03-30 18:30:36

+0

@JoeZephyr:就是这样;)请看看我的更新了。 – 2011-03-30 18:36:39

我知道这是一个老问题,但我看到,在该评论,$ .proxy()被提及。是的,它确实会改变对象的上下文,但不会改变jQuery事件。

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

$ .proxy()返回this下文称在范围的功能,但是,则返回并通过click()然后改变范围.selector元件中使用该功能。

我一分钟前测试,但如果我听错了,请不要告诉

+4

不知道这是不是在旧的jQuery版本,但这个例子显示你是错的:http://jsfiddle.net/mazztgc9/。 – 2015-07-08 10:19:58