2010-10-25 42 views
5

Tôi đang có một khoảng thời gian thực sự thô ráp bao quanh đầu của tôi xung quanh các nguyên mẫu trong JavaScript.Không thể sử dụng các phương thức "lớp" cho các cuộc gọi lại trong JavaScript

Trước đây tôi đã gặp rắc rối gọi một cái gì đó như thế này:

o = new MyClass(); 
setTimeout(o.method, 500); 

và tôi đã nói với tôi có thể sửa chữa nó bằng cách sử dụng:

setTimeout(function() { o.method(); }, 500); 

Và công trình này. Bây giờ tôi đang gặp một vấn đề khác, và tôi nghĩ tôi có thể giải quyết nó theo cùng một cách, bằng cách chỉ bỏ một chức năng vô danh. vấn đề mới của tôi là thế này:

MyClass.prototype.open = function() { 
    $.ajax({ 
     /*...*/ 
     success: this.some_callback, 
    }); 
} 

MyClass.prototype.some_callback(data) { 
    console.log("received data! " + data); 
    this.open(); 
} 

Tôi thấy rằng trong cơ thể của MyClass.prototype.some_callback từ khóa this không đề cập đến trường hợp của MyClass mà phương pháp này đã được kêu gọi, mà là những gì dường như là jQuery yêu cầu ajax (nó là một đối tượng có chứa một đối tượng xhr và tất cả các tham số của cuộc gọi ajax của tôi, trong số những thứ khác).

Tôi đã cố gắng làm điều này:

$.ajax({ 
    /* ... */ 
    success: function() { this.some_callback(); }, 
}); 

nhưng tôi nhận được lỗi:
Uncaught TypeError: Object #<an Object> has no method 'handle_response'

Tôi không chắc chắn làm thế nào để làm đúng cách này. Tôi mới sử dụng JavaScript và khái niệm về nguyên mẫu-đôi khi-loại-hành vi-như-lớp-nhưng-thường-không thực sự gây nhầm lẫn cho tôi.

Vì vậy, cách phù hợp để làm điều này là gì? Tôi đang cố gắng để buộc JavaScript vào một mô hình mà nó không thuộc về?

Trả lời

12

Am I trying to force JavaScript into a paradigm which it doesn't belong?

Khi bạn đang nói về Lớp học có.

So what is the right way to do this?

Trước hết, bạn nên tìm hiểu xem loại giá trị mà từ khóa this có thể chứa.

  1. đơn giản chức năng gọi

    myFunc(); - this sẽ đề cập đến đối tượng toàn cầu (aka window) [1] Cuộc gọi

  2. Chức năng như một thuộc tính của một đối tượng (hay còn gọi là phương pháp)

    obj.method(); - this sẽ tham khảo obj

  3. gọi Function cùng wit các nhà điều hành mới

    new MyFunc(); - this sẽ tham khảo các new instance được tạo ra

Bây giờ chúng ta hãy xem làm thế nào nó áp dụng cho trường hợp của bạn:

MyClass.prototype.open = function() { 
    $.ajax({ // <-- an object literal starts here 
     //... 
     success: this.some_callback, // <- this will refer to that object 
    });  // <- object ends here 
} 

Nếu bạn muốn gọi phương thức some_callback của cá thể hiện tại, bạn nên lưu tham chiếu đến cá thể đó (vào một biến đơn giản).

MyClass.prototype.open = function() { 
    var self = this; // <- save reference to the current instance of MyClass 
    $.ajax({ 
     //... 
     success: function() { 
      self.some_callback(); // <- use the saved reference 
     }       // to access instance.some_callback 
    });        
} 

[1] xin lưu ý rằng trong phiên bản mới (ES 5 Str.) Trường hợp 1 sẽ gây ra this là giá trị undefined

[2] Có thêm một trường hợp bạn sử dụng call hoặc apply để gọi một chức năng với một trao this

+0

okay, tôi đã cố gắng này, nhưng kết quả của tôi là như nhau: cuộc gọi cho 'công trình some_callback', nhưng' this' bên trong của 'some_callback' đề cập đến một đối tượng yêu cầu jax mà bạn đã đánh dấu trong ví dụ mã đầu tiên của mình. Làm thế nào tôi có thể gọi 'some_callback' theo cách mà, trong callback,' this' sẽ tham chiếu đến đối tượng 'MyClass' đặt callback? –

+0

Tôi gặp lỗi nhỏ. Đã cập nhật câu trả lời. – galambalazs

+0

ví dụ cập nhật của bạn hoạt động như một sự quyến rũ. Tôi nghĩ rằng tôi đã thử nó và nó đã không hoạt động ... Tôi cho rằng tôi đã phạm sai lầm khi tôi thử phương pháp đó trước đó. –

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