2011-12-13 32 views
5

tôi có mã này (JSFiddle)Làm cách nào để tôi có thể xử lý chính xác phương thức "công khai" này?

var OBJ = function(){ 
    var privateVar = 23; 
    var self = this; 

    return { 
     thePrivateVar : function() { 
      return privateVar; 
     }, 

     thePrivateVarTimeout : function() { 
      setTimeout(function() { alert(self.thePrivateVar()); } , 10); 
     } 
    } 

}(); 

alert(OBJ.thePrivateVar()); 

OBJ.thePrivateVarTimeout(); 

Đây là một khái niệm trừu tượng của một vấn đề thực sự tôi đang gặp.

Vì vậy - tôi mong đợi cuộc gọi đến OBJ.thePrivateVarTimeout() để chờ 10 và sau đó alert với 23 (mà tôi muốn truy cập thông qua phương pháp tiếp xúc khác).

Tuy nhiên self dường như không được đặt chính xác. Khi tôi thiết lập self = this, có vẻ như this không phải là tham chiếu đến hàm mà là tham chiếu đến đối tượng chung. Tại sao điều này?

Tôi làm cách nào để đặt phương thức công khai thePrivateVarTimeout gọi phương thức công khai khác thePrivateVar?

+2

* Tại sao điều này? * Bởi vì bạn đang gọi hàm thường ('func()'). Trong trường hợp này, 'this' luôn đề cập đến đối tượng chung. Nếu bạn muốn nó tham chiếu đến một đối tượng rỗng, hoặc gọi nó bằng 'new' hoặc gán một cái:' var self = {}; '. –

+0

@FelixKling Cảm ơn điều này làm cho 'self' được đặt chính xác. Tôi vẫn không thể sử dụng nó để gọi 'thePrivateVar'. Tôi nghĩ câu trả lời của Raynos là cách tôi nên làm. –

Trả lời

5
var OBJ = (function(){ 
    var privateVar = 23; 
    var self = { 
     thePrivateVar : function() { 
      return privateVar; 
     }, 

     thePrivateVarTimeout : function() { 
      setTimeout(function() { alert(self.thePrivateVar); } , 10); 
     } 
    }; 

    return self; 

}()); 

this === global || undefined bên trong hàm được gọi. Trong ES5, bất kể môi trường toàn cầu là gì, trong ES5 nghiêm ngặt thì nó không được xác định.

mẫu Phổ biến hơn sẽ bao gồm việc sử dụng var that = this như một giá trị địa phương trong một chức năng

var obj = (function() { 
    var obj = { 
    property: "foobar", 
    timeout: function _timeout() { 
     var that = this; 
     setTimeout(alertData, 10); 

     function alertData() { 
     alert(that.property); 
     } 
    } 
    } 

    return obj; 
}()); 

hoặc sử dụng một phương pháp .bindAll

var obj = (function() { 
    var obj = { 
    alertData: function _alertData() { 
     alert(this.property); 
    } 
    property: "foobar", 
    timeout: function _timeout() { 
     setTimeout(this.alertData, 10); 
    } 
    } 

    bindAll(obj) 

    return obj; 
}()); 


/* 
    bindAll binds all methods to have their context set to the object 

    @param Object obj - the object to bind methods on 
    @param Array methods - optional whitelist of methods to bind 

    @return Object - the bound object 
*/ 
function bindAll(obj, whitelist) { 
    var keys = Object.keys(obj).filter(stripNonMethods); 

    (whitelist || keys).forEach(bindMethod); 

    function stripNonMethods(name) { 
     return typeof obj[name] === "function"; 
    } 

    function bindMethod(name) { 
     obj[name] = obj[name].bind(obj); 
    } 

    return obj; 
} 
+0

Cảm ơn, tôi đã sử dụng mẫu đầu tiên. Tôi không thực sự cần 'self' là một tham chiếu đến tổng thể' OBJ' - tôi chỉ cần các phương thức công khai để có thể gọi cho nhau. Tuy nhiên, Felix cũng giải quyết vấn đề 'self'. –

+0

@ElRonnoco Cá nhân tôi thích mẫu '.bindAll' hơn vì' that = this' làm cho mắt tôi chảy máu. – Raynos

+1

@Raynos trong dòng 'pd.bindAll (obj)' pd' là gì hoặc pd xuất phát từ đâu? –

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