2010-07-23 4 views
14

Tôi là một người mới bắt đầu để đóng cửa (và javscript nói chung), và tôi không thể tìm thấy một lời giải thích thỏa đáng về những gì đang xảy ra trong mã này:Tại sao việc đóng cửa này không có quyền truy cập vào từ khóa 'này'? - jQuery

function myObject(){ 
    this.myHello = "hello"; 
    this.myMethod = do_stuff; 
} 

function do_stuff(){ 
    var myThis = this; 
    $.get('http://example.com', function(){ 
     alert(this.myHello); 
     alert(myThis.myHello); 
    }); 
} 

var obj = new myObject; 
obj.myMethod(); 

Nó sẽ cảnh báo 'undefined' và sau đó 'xin chào'. Rõ ràng đây không phải là jQuery cụ thể, nhưng đây là hình thức đơn giản nhất của mã ban đầu của tôi tôi có thể đưa ra. Việc đóng cửa trong do_stuff() có quyền truy cập vào các biến trong phạm vi đó, nhưng dường như quy tắc này không áp dụng cho từ khóa this.

Câu hỏi:

gì xảy ra với this khi đóng cửa được chuyển ngoài phạm vi của do_stuff() (trong trường hợp này $.get())? myThis có chứa bản sao của this hoặc tham chiếu đến nó không? Có thường không phải là ý tưởng hay khi sử dụng this khi đóng cửa?

Bất kỳ phản hồi nào được đánh giá cao.

Trả lời

8

Điều gì xảy ra với điều này khi việc đóng cửa được chuyển ra ngoài phạm vi của do_stuff() (trong trường hợp này là $ .get())?

Mỗi hàm có ngữ cảnh thực thi riêng, từ khóa this truy lục giá trị của ngữ cảnh hiện tại.

Các doStuff nhận dạng và obj.myMethod tài sản tham khảo các đối tượng chức năng tương tự, nhưng kể từ khi bạn đang gọi nó như là một tài sản của một đối tượng (obj.myMethod();), giá trị this bên trong chức năng đó, sẽ tham khảo obj.

Khi yêu cầu Ajax đã thành công, jQuery sẽ gọi hàm thứ hai (bắt đầu ngữ cảnh thực thi mới) và nó sẽ sử dụng đối tượng chứa các cài đặt được sử dụng cho yêu cầu làm giá trị this của cuộc gọi đó.

Bản đồ này có chứa bản sao của tài liệu này hoặc tham chiếu đến nó không?

Từ định danh myThis sẽ chứa một tham khảo đến đối tượng đó cũng được tham chiếu bởi giá trị this trên phạm vi bên ngoài.

Bạn thường không nên sử dụng tính năng này trong bao đóng?

Nếu bạn hiểu cách giá trị this được xử lý ngầm, tôi không thấy bất kỳ sự cố nào ...

Vì bạn đang sử dụng jQuery, bạn có thể muốn kiểm tra các phương pháp jQuery.proxy, là một phương pháp hữu ích có thể được sử dụng để bảo vệ bối cảnh của một hàm, ví dụ:

function myObject(){ 
    this.myHello = "hello"; 
    this.myMethod = do_stuff; 
} 

function do_stuff(){ 
    $.get('http://example.com', jQuery.proxy(function(){ 
     alert(this.myHello); 
    }, this)); // we are binding the outer this value as the this value inside 
} 

var obj = new myObject; 
obj.myMethod(); 

Xem thêm:

+0

Tôi sẽ yêu cầu theo dõi nhưng bản chỉnh sửa mới nhất của bạn đã trả lời câu hỏi đó. Cảm ơn! – thewiglaf

+0

@thewiglaf: Bạn được chào đón! Hãy bình luận nếu bạn có bất kỳ nghi ngờ ... – CMS

2
$.get('http://example.com', function(){ 
    alert(this.myHello); // this is scoped to the function 
    alert(myThis.myHello); // myThis is 'closed-in'; defined outside 
}); 

lưu ý chức năng ẩn danh. điều này trong phạm vi đó là phạm vi của hàm. myThis là điều này của phạm vi bên ngoài, nơi myHello đã được xác định. Kiểm tra nó trong firebug.

'this' luôn luôn đề cập đến phạm vi thực hiện hiện tại, tôi tin tưởng. Nếu bạn muốn lấy phạm vi hiện tại và bảo toàn nó, bạn làm những gì bạn đã làm, điều này được gán cho biến khác.

1
$.get('http://example.com', function(){ 
    // inside jQuery ajax functions - this == the options used for the ajax call 
}); 

Điều gì xảy ra với điều này khi đóng cửa được chuyển ra ngoài phạm vi của do_stuff() (trong trường hợp này là $ .get())?

Không có gì "xảy ra" với nó, đây vẫn này là dành cho việc đóng cửa mà, bối cảnh thực hiện các chức năng gọi từ việc đóng cửa không tự động kế thừa this.

Bản đồ này có chứa bản sao của tài liệu này hoặc tham chiếu đến nó không?

Tất cả các bài tập không phải là vô hướng là tham chiếu trong JavaScript. Vì vậy, nó là một tham chiếu đến this, nếu bạn thay đổi các thuộc tính trên một trong hai, chúng thay đổi cho cả hai.

Bạn thường không nên sử dụng tính năng này trong bao đóng?

Nó thường là một ý tưởng tốt để sử dụng this trong đóng cửa, nhưng nếu bạn đang đi để được sử dụng đóng cửa bên trong mà cần phải truy cập vào cùng một this, thực hành tốt của mình để thực hiện chính xác những gì bạn đã làm: var someName = this; và sau đó truy cập bằng cách sử dụng someName