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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5490448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:24:48  来源:igfitidea点击:

How do I pass the this context into an event handler?

javascriptjavascript-events

提问by josef.van.niekerk

I know this question doesn't make much sense, but let me try and clarify a bit.

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

I have a class, called ScrollBanner, and it looks somewhat as follows (a lot omitted for brevity):

我有一个名为 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() {
        //...
    }
}

As you can see this.initializesets a click handler to this._onClickNavigation. Some might expect the thisinside the event handler to refer to the ScrollBannerinstance, but sadly it doesn't. It refers to the element that trigerred the click event, in this case span#banner1-nav

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

What would be the best way to get thisto refer to the ScrollBannerclass instance?

什么是得到的最好方式指的ScrollBanner类的实例?

回答by Felix Kling

The old/traditional way:

旧/传统方式:

Capture thisin a variable:

this在变量中捕获:

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

You could also assign thisto a variable e.g. instance:

您还可以分配this给一个变量,例如instance

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

and refer to instanceinstead of thisin all the calls.

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

The overall idea is to store thisin a variable in a higher scope.

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



The ECMAScript5 way:

ECMAScript5 方式:

ECMAScript5 introduces a new property of functions: .bind(). MDC's documentationshows an implementation for browsers that don't support it. With it you can bind a certain context to a function:

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

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

but behind the scenes it is doing the same thing. The advantage is that you make use of built-in functionality in browser that support is.

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

Note that this is different from applyor call. Both of these set the context andexecute the function, whereas bindonly sets the context without executing the function.

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



The jQuery way:

jQuery方式:

jQuery provides a method $.proxy()that is doing the same:

jQuery 提供了一种$.proxy()执行相同操作的方法:

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

回答by Mario Legenda

I know this is an old question, but I saw, that in the comments, $.proxy() is mentioned. Yes, it does change the context of an object but not in an jQuery event.

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

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

$.proxy() returns the function in the scope that thisreffered but then that function is returned and used by click()which then changes the scope to .selectorelement.

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

I've tested it a minute ago but if i got it wrong, please, do tell

一分钟前我已经测试过了,但如果我做错了,请告诉