简体   繁体   English

从回调中调用 javascript 对象方法

[英]Invoke a javascript object method from within a callback

I define the following MyClass and 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_xmlhttpRequest completes.该脚本有效,一旦GM_xmlhttpRequest完成,就会调用myCallback()方法。

However, it only works because the onload callback is referring to the global variable myClassInstance .但是,它仅起作用是因为onload回调引用了全局变量myClassInstance If I update the onload callback to:如果我将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 this is being evaluated in the wrong context.似乎this是在错误的上下文中进行评估的。

Is there a way to invoke the myCallback() method of myClassInstance without having to resort to using a global variable?有没有一种方法来调用myCallback()的方法myClassInstance ,而不必诉诸使用全局变量?

Save the correct this , when it is in scope, into a variable.当它在范围内时,将正确的this保存到一个变量中。 Then you can reference it later:然后你可以稍后参考它:

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

The simplest solution, as already was pointed out, is creating an alias for the this that stays in scope.正如已经指出的,最简单的解决方案是为保持在作用域内的this创建一个别名。 The most popular variable names for the alias are things like self or that , but anything works, really.别名最流行的变量名称是selfthat类的东西,但实际上任何东西都有效。

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

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();
            }
        });
    };
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM