2010-12-10 14 views

Respuesta

15

Puede devolver una referencia a él ...

var a = function() { 

    var b = function() { 
     // I'm private! 
     alert('go away!'); 
    }; 

    return { 
     b: b // Not anymore! 
    }; 

}; 

See it on jsFiddle.

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).

+0

+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

+0

¡Gracias! ¿Podemos exponerlo de la misma manera si se trata de una función anónima? – paul

+0

@paul Sí, 'return function() {}'. – alex

7

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!" 
+0

+1 porque creo que merece uno :) – alex

+0

window es un objeto global. ¿Es una buena manera de usar un objeto global para exponer un método? – paul

+0

@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

3

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 
+0

gracias! ... por la explicación ... – paul

0

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" 
Cuestiones relacionadas