2010-02-12 41 views
7

Tôi có một lớp JavaScript mà trông như thế này:Phạm vi "này" trong JavaScript

function SomeFunction() 
{ 
    this.doSomething(function() 
    { 
     this.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 

Mã này ném một lỗi vì phạm vi "này" bên trong hàm đó được thông qua vào doSomething() là khác với phạm vi của "điều này" bên ngoài hàm đó.

Tôi hiểu tại sao điều này xảy ra, nhưng cách tốt nhất để giải quyết vấn đề này là gì? Đây là những gì tôi sẽ làm:

function SomeFunction() 
{ 
    var thisObject = this; 

    this.doSomething(function() 
    { 
     thisObject.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 

Điều đó hoạt động tốt, nhưng nó chỉ cảm thấy như một hack. Chỉ cần tự hỏi nếu ai đó có một cách tốt hơn.

+2

@Jon Kruger Đó cũng là những gì tôi làm. Tôi nghĩ điều đó khá bình thường. Bạn có thể thay đổi 'this' bằng' call' và 'apply', nhưng điều đó không phải lúc nào cũng phù hợp với những gì bạn đang làm tốt. Một tùy chọn khác là truyền 'this' như một tham số, nhưng điều đó có vẻ giống như một hack. –

+0

@Jonathon Ý của bạn là gì "Bạn có thể thay đổi điều này bằng cuộc gọi và áp dụng"? –

+1

@Jon Kruger Xem điều này, hãy xem bài viết của họ về 'cuộc gọi': https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Apply –

Trả lời

10

Đó là giải pháp đúng và thường được chấp nhận. Đó là loại kludgy nhưng đó là những gì mọi người làm. Thông thường, biến phụ này có tên là self, như sau:

+1

Lưu ý rằng 'self' là thuộc tính của đối tượng cửa sổ trong các trình duyệt trỏ vào chính nó, mặc dù điều này không có khả năng gây ra bất kỳ sự cố nào. –

+0

Các tên khác mà tôi đã thấy được sử dụng khá nhiều là 'that' và' me', tùy thuộc vào ngữ cảnh. – cHao

3

this có phạm vi "động". Điều đó có nghĩa rằng nó được thiết lập bởi bất cứ điều gì liên kết nó, và this bị ràng buộc bởi một "cuộc gọi phương thức". Đó là, bất cứ lúc nào trong chương trình của bạn, bạn thấy điều này: w.f() sau đó trong khi f được thực thi, this là tự động bị ràng buộc để f, thậm chí nếu fthis trong phạm vi từ vựng của mình.

Hầu hết các khung JavaScript cung cấp một số phương tiện để giải quyết vấn đề chính xác này. Với Prototype.js (ví dụ) bạn có thể làm điều này:

this.doSomething(function() { this.doSomethingElse(); }.bind(this)); 

Tuy nhiên, "hack" của bạn vẫn ổn. Tôi thường làm một (function (self) { ... })(this) xung quanh bất kỳ chức năng nào mà tôi cần một biến số tương tự như vi phạm this.

1

Cũng đáng nói rằng phiên bản tiếp theo của ECMAScript (thông số ngôn ngữ cho JavaScript) sẽ giới thiệu Function.bind(), điều này sẽ cho phép bạn chỉ định ngữ cảnh cố định cho một hàm.