我在用户脚本中定义了以下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'。
似乎在错误的背景下评估this
。
有没有办法调用myCallback()
myClassInstance
方法而不必使用全局变量?
答案 0 :(得分:31)
将正确的this
保存在变量中。然后你可以在以后引用它:
this.startRequest = function() {
var myself = this;
GM_xmlhttpRequest({
'method': 'GET',
'url': "http://www.google.com/",
'onload': function (xhr) {
myself.myCallback();
}
});
};
答案 1 :(得分:6)
正如已经指出的那样,最简单的解决方案是为保留在范围内的this
创建别名。别名最受欢迎的变量名称是self
或that
之类的东西,但实际上它们都有效。
另一种替代方案(可能会或可能不会更好,取决于用例)将方法绑定到“普通”函数并使用它来代替:
var f = this.callback.bind(this);
...
'onload': function(){
f();
}
旧浏览器不支持bind,但您可以在许多JS框架中找到替代方法。我给出的示例看起来不太好,但是当你想直接将你的方法作为回调函数传递时,它会非常方便(你也可能得到部分函数应用程序,而且非常整洁)
答案 2 :(得分:3)
存储对实例的引用并使用它:
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();
}
});
};
}