2011-12-13 19 views
5

Mam ten kod (JSFiddle)Jak poprawnie zakreślić tę "publiczną" metodę?

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

To jest abstrakcją prawdziwego problemu mam.

Tak więc oczekiwałbym połączenia z OBJ.thePrivateVarTimeout(), aby czekać 10, a następnie alert z 23 (które chcę, aby uzyskać dostęp za pośrednictwem innych narażonych metoda).

Jednak ustawienie self nie wydaje się być prawidłowe. Kiedy ustawiam self = this, wydaje się, że this nie jest odniesieniem do funkcji, ale odniesieniem do obiektu globalnego. Dlaczego to?

Jak udostępnić publiczną metodę thePrivateVarTimeout zadzwonić pod inną publiczną metodę thePrivateVarTimeout zadzwonić do innej publicznej metody ?

+2

* Dlaczego jest to? * Bo jesteś wywołanie funkcji normalnie ('func()'). W tym przypadku "this" zawsze odnosi się do obiektu globalnego. Jeśli chcesz, aby odwoływał się do pustego obiektu, wywołaj go za pomocą 'new' lub przypisz jeden:' var self = {}; '. –

+0

@FelixKling Dzięki temu 'self' ustawiony jest poprawnie. Nadal nie mogę go użyć do wywołania 'thePrivateVar' chociaż. Myślę, że odpowiedź Raynosa jest taka, jak powinienem to zrobić. –

Odpowiedz

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 wewnątrz wywoływanej funkcji. W ES5 nie ma znaczenia, jakie jest środowisko globalne, w ES5 jest ono nieokreślone.

bardziej powszechne wzorce wiązałoby pomocą var that = this jako wartość lokalnej w funkcji

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

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

    return obj; 
}()); 

lub stosując metodę .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

Dzięki, użyłem pierwszego wzoru. Naprawdę nie potrzebuję "self", aby być odniesieniem do ogólnego "OBJ" - po prostu potrzebuję publicznych metod, aby móc się nawzajem nazywać. Jednak Felix również zajął się problemem "ja". –

+0

@ ElRonnoco Osobiście wolę wzór '.index, ponieważ' that = this' sprawia, że ​​moje oczy krwawią. – Raynos

+1

@Raynos w linii 'pd.bindAll (obj)' czym jest 'pd' lub skąd pochodzi pd? –

Powiązane problemy