从回调中调用 javascript 对象方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6985288/
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-10-25 22:35:46  来源:igfitidea点击:

Invoke a javascript object method from within a callback

javascriptcallbackjavascript-objects

提问by Jason

I define the following MyClassand its methods in a user script:

MyClass在用户脚本中定义了以下内容及其方法:

function MyClass() {
    this.myCallback = function() {
        alert("MyClass.myCallback()");
    };

    this.startRequest = function() {
        GM_xmlhttpRequest({
            'method': 'GET',
            'url': "http://www.google.com/",
            'onload': function (xhr) {
                myClassInstance.myCallback();
            }
        });
    };
}

var myClassInstance = new MyClass();
myClassInstance.startRequest();

This script works and the myCallback()method gets called once the GM_xmlhttpRequestcompletes.

此脚本有效,并且myCallback()一旦GM_xmlhttpRequest完成,就会调用该方法。

However, it only works because the onloadcallback is referring to the global variable myClassInstance. If I update the onloadcallback to:

但是,它仅起作用是因为onload回调引用了全局变量myClassInstance。如果我将onload回调更新为:

'onload': function (xhr) {
    this.myCallback();
}

Then I get the (Chrome) error:

然后我收到(Chrome)错误:

Uncaught TypeError: Object [object DOMWindow] has no method 'myCallback'.

未捕获的类型错误:对象 [对象 DOMWindow] 没有方法“myCallback”。

It seems thisis being evaluated in the wrong context.

似乎this是在错误的上下文中进行评估。

Is there a way to invoke the myCallback()method of myClassInstancewithout having to resort to using a global variable?

有没有办法调用 的myCallback()方法myClassInstance而不必求助于使用全局变量?

回答by Jeremy

Save the correct this, when it is in scope, into a variable. Then you can reference it later:

this在范围内将正确的 保存到变量中。然后你可以稍后参考它:

 this.startRequest = function() {
     var myself = this;
     GM_xmlhttpRequest({
         'method': 'GET',
         'url': "http://www.google.com/",
         'onload': function (xhr) {
             myself.myCallback();
         }
     });
 };

回答by hugomg

The simplest solution, as already was pointed out, is creating an alias for the thisthat stays in scope. The most popular variable names for the alias are things like selfor that, but anything works, really.

正如已经指出的,最简单的解决方案是为this保持在范围内的创造一个别名。别名最流行的变量名是selfor 之类的东西that,但实际上任何东西都有效。

The other alternative (that might or might not be better, depending on the use case) is binding the method into a "plain" function and using that instead:

另一种选择(可能更好也可能不会更好,取决于用例)是将方法绑定到“普通”函数并使用它:

var f = this.callback.bind(this);

...
'onload': function(){
    f();
}

bind is not supported on old browsers, but you can find alternatives in many JS frameworks. The example I gave doesn't look that good, but it can be very convenient when you want to pass your method directly as a callback function (you might also get partial function application as well and that is very neat)

旧浏览器不支持绑定,但您可以在许多 JS 框架中找到替代方案。我给出的例子看起来不太好,但是当你想直接将你的方法作为回调函数传递时它会非常方便(你也可能得到部分函数应用程序,这非常简洁)

回答by JAAulde

Store a reference to the instance and use it:

存储对实例的引用并使用它:

function MyClass() {
    this.myCallback = function() {
        alert("MyClass.myCallback()");
    };

    var instance = this;

    instance.startRequest = function() {
        GM_xmlhttpRequest({
            'method': 'GET',
            'url': "http://www.google.com/",
            'onload': function (xhr) {
                instance.myCallback();
            }
        });
    };
}