2011-12-13 34 views
5

tengo este código (JSFiddle)¿Cómo puedo aplicar este método "público" correctamente?

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

Ésta es una abstracción de un verdadero problema que estoy teniendo.

Por lo tanto - Yo esperaría que la llamada a OBJ.thePrivateVarTimeout() que esperar 10 y luego alert con 23 (que yo quiero que el acceso a través de otro método expuesto).

Sin embargo, self parece no estar configurando correctamente. Cuando configuro self = this, parece que this no es una referencia a la función sino una referencia al objeto global. ¿Por qué es esto?

¿Cómo puedo hacer que el método público thePrivateVarTimeout llame al otro método público thePrivateVar?

+2

* ¿Por qué es esto? * Porque se está llamando a la función normalmente ('func()'). En este caso, 'this' siempre se refiere al objeto global. Si desea que se refiera a un objeto vacío, llámelo con 'nuevo' o asigne uno:' var self = {}; '. –

+0

@FelixKling Gracias esto hace 'self' establecido correctamente. Todavía no puedo usarlo para invocar 'thePrivateVar'. Creo que la respuesta de Raynos es la forma en que debería hacerlo. –

Respuesta

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 dentro de una función invocada. En ES5 es lo que sea que el entorno global sea, en ES5 estricto no está definido.

patrones más comunes implicarían el uso de la var that = this como un valor local en una función

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

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

    return obj; 
}()); 

o el uso de un método .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

Gracias, utilicé el primer patrón. Realmente no necesito que "yo" sea una referencia al "OBJ" en general, solo necesito los métodos públicos para poder llamarme entre ellos. Sin embargo, Félix también abordó el problema del 'yo'. –

+0

@ElRonnoco Personalmente prefiero el patrón '.bindAll' porque' that = this' hace que mis ojos sangren. – Raynos

+1

@Raynos en la línea 'pd.bindAll (obj)' ¿qué es 'pd' o de dónde viene el pd? –

Cuestiones relacionadas