Cuando estamos creando un método dentro de un cierre, se convierte en privado para ese cierre y no se puede acceder hasta que lo expongamos de alguna manera.Exponer un método que está dentro de un cierre
¿Cómo se puede exponer?
Cuando estamos creando un método dentro de un cierre, se convierte en privado para ese cierre y no se puede acceder hasta que lo expongamos de alguna manera.Exponer un método que está dentro de un cierre
¿Cómo se puede exponer?
Puede devolver una referencia a él ...
var a = function() {
var b = function() {
// I'm private!
alert('go away!');
};
return {
b: b // Not anymore!
};
};
También podría bind it to the window
object. Pero prefiero el método anterior, de lo contrario lo está exponiendo a través de una variable global (que es una propiedad del objeto window
).
Necesita pasarlo al exterior de alguna manera.
Ejemplo:http://jsfiddle.net/patrick_dw/T9vnn/1/
function someFunc() {
var privateFunc = function() {
alert('expose me!');
}
// Method 1: Directly assign it to an outer scope
window.exposed = privateFunc;
// Method 2: pass it out as a function argument
someOuterFunction(privateFunc);
// Method 3: return it
return privateFunc;
}
someFunc()(); // alerts "expose me!"
function someOuterFunction(fn) {
fn(); // alerts "expose me!"
}
window.exposed(); // alerts "expose me!"
+1 porque creo que merece uno :) – alex
window es un objeto global. ¿Es una buena manera de usar un objeto global para exponer un método? – paul
@paul - Estoy de acuerdo con @alex y digo que no. Lo acabo de usar como un ejemplo genérico. Puede asignarlo a cualquier ámbito al que tenga acceso. – user113716
Usted expone las funciones o propiedades de un cierre declarando internamente en este alcance (que puede cambiar en función de invocación).
function example(val) {
var value = val;
this.getVal = function() {
return value;
}
this.setVal = function(v) {
value = v;
}
}
var ex = new example(2);
ex.getVal(); // == 2
ex.setVal(4); // == null
ex.getVal(); // == 4
métodos declarados en este puede acceder a las variables declaradas utilizando var , pero no al revés'.
function example(val) {
var value = val;
var double = function(v) {
return 2 * v;
}
this.getDouble = function() {
return double(value);
}
}
var ex = new example(2);
ex.getDouble(); // == 4
La funciónse cierra sobre el alcance. Lo que desea hacer es devolver una referencia a una función que tenga acceso al alcance que necesita para poder invocarlo en un momento posterior.
Si necesita crear una función que llama a un método específico en algún momento más tarde,
var ex = new example(2);
var delayed_call = function() {
return(ex.getDouble()); // == 4, when called
}
setTimeout(delayed_call, 1000);
Si alcance es un problema,
var ex = new example(2);
var delayed_call = (function(ex_ref) {
return function() {
return(ex_ref.getDouble()); // == 4, when called
}
})(ex); // create a new scope and capture a reference to ex as ex_ref
setTimeout(delayed_call, 1000);
Puede inline la mayor parte de esto con el menor ejemplo legible,
setTimeout((function(ex_ref) {
return function() {
return(ex_ref.getDouble()); // == 4, when called
})(new example(2)))
, 1000
);
setTimeout es solo una manera conveniente de demostrar la ejecución en un nuevo alcance.
var ex = new example(2);
var delayed_call = function() {
return(ex.getDouble());
}
delayed_call(); // == 4
gracias! ... por la explicación ... – paul
Por motivos de rendimiento puede invocar esta manera:
var a = (function(){
function _a(){}
_a.prototype = (function(){
var _test = function(){ console.log("test"); };
return {
test: _test
}
}());
return new _a();
}());
// usage
var x = a;
x.test(); // "test"
+1. OP, deberías echar un vistazo a este ebook: http://addyosmani.com/blog/essentialjsdesignpatterns/. Esto se conoce como el patrón "Revelar Módulo". – simshaun
¡Gracias! ¿Podemos exponerlo de la misma manera si se trata de una función anónima? – paul
@paul Sí, 'return function() {}'. – alex