2011-08-08 28 views
12

tôi xác định như sau MyClass và phương pháp của nó trong một kịch bản sử dụng:Gọi một phương pháp đối tượng javascript từ bên trong một callback

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

kịch bản này hoạt động và phương pháp myCallback() được gọi khi GM_xmlhttpRequest hoàn tất.

Tuy nhiên, nó chỉ hoạt động vì cuộc gọi lại onload đề cập đến biến toàn cục myClassInstance. Nếu tôi cập nhật onload callback để:

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

Sau đó, tôi nhận được (Chrome) lỗi:

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

Nó dường như this đang được đánh giá trong bối cảnh sai.

Có cách nào để gọi phương thức myCallback() của myClassInstance mà không phải sử dụng biến toàn cục?

Trả lời

23

Lưu chính xác this, khi nó nằm trong phạm vi, thành một biến. Sau đó, bạn có thể tham khảo nó sau này:

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

+1 đánh tôi với nó – JAAulde

+4

+1 Bạn vừa kết thúc phiên làm việc dài đầu giờ. Cảm ơn bạn. :) – Anthony

2

Lưu trữ một tham chiếu đến thể hiện và sử dụng nó:

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

Giải pháp đơn giản nhất, như đã được chỉ ra, đang tạo ra một bí danh cho this mà vẫn trong phạm vi. Tên biến phổ biến nhất cho bí danh là những thứ như self hoặc that, nhưng mọi thứ đều hoạt động.

Các thay thế khác (mà có thể hoặc không có thể là tốt hơn, tùy từng trường hợp sử dụng) có tính ràng buộc pháp vào một chức năng "đồng bằng" và sử dụng rằng thay vì:

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

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

ràng buộc không được hỗ trợ trên cũ trình duyệt, nhưng bạn có thể tìm thấy các lựa chọn thay thế trong nhiều khung công tác JS. Ví dụ tôi đưa ra không có vẻ tốt, nhưng nó có thể rất thuận tiện khi bạn muốn chuyển trực tiếp phương thức của bạn như một hàm gọi lại (bạn cũng có thể nhận được một phần chức năng ứng dụng và rất gọn gàng)

+2

Hãy cẩn thận với 'self' vì' window.self'. – Jeremy

Các vấn đề liên quan