从回调中调用javascript对象方法

从回调中调用javascript对象方法,javascript,callback,javascript-objects,Javascript,Callback,Javascript Objects,我在用户脚本中定义了以下MyClass及其方法: function MyClass() { this.myCallback = function() { alert("MyClass.myCallback()"); }; this.startRequest = function() { GM_xmlhttpRequest({ 'method': 'GET', 'url': "http://w

我在用户脚本中定义了以下
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();
这个脚本可以工作,一旦GM_xmlhttpRequest完成,就会调用
myCallback()
方法

但是,它之所以有效,是因为
onload
回调引用的是全局变量
myClassInstance
。如果我将
onload
回调更新为:

'onload': function (xhr) {
    this.myCallback();
}
然后我得到(Chrome)错误:

未捕获的TypeError:对象[Object DOMWindow]没有方法“myCallback”

似乎在错误的上下文中对该进行了评估


有没有一种方法可以调用
myClassInstance
myCallback()
方法而不必使用全局变量?

将正确的
保存到变量中(当它在范围内时)。然后,您可以稍后参考它:

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

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

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

如前所述,最简单的解决方案是为范围内的
this
创建别名。别名中最流行的变量名是
self
that
,但实际上任何东西都可以工作

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

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

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

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

小心
self
,因为
window.self
+1您刚刚结束了我长达一小时的头痛会话。谢谢。:)