2011-08-08 47 views
12

我定義中調用一個JavaScript對象的方法如下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(); 

此腳本工作和myCallback()方法被調用一次GM_xmlhttpRequest完成。

但是,它僅適用於onload回調指的是全局變量myClassInstance。如果我更新onload回調:

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

然後我得到的(鉻)錯誤:

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

它似乎this被錯誤的上下文中計算。

有沒有辦法使用myClassInstance來調用myCallback()方法,而不必求助於使用全局變量?

回答

23

保存正確的this,當它在範圍,到一個變量。然後你就可以在以後引用它:

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

+1打敗了我。 – JAAulde

+4

+1你剛剛結束了我的小時長頭猛擊會議。謝謝。 :) – Anthony

2

商店一個參考實例,並使用它:

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

最簡單的解決辦法,因爲已經有人指出,對於那些停留在this創建別名在適用範圍。別名最常用的變量名稱是selfthat,但是其他任何東西都可以。

另一種選擇(可能是也可能不是更好,這取決於使用情況)被結合方法爲「普通」的功能,並使用該代替:

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

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

綁定不支持老瀏覽器,但你可以在許多JS框架中找到替代品。我給的例子看起來不那麼好,但它可以當你想直接傳遞你的方法作爲一個回調函數非常方便(你也可能會得到部分功能應用,以及這是非常整齊)

+2

小心''因爲的window.self' self'。 – Jeremy