Normalmente, veo el cierre de la función logrado por la forma

var closedF = (function()
{
    return function(){/* return value */}
})();

Para que llamar closedF() devuelva el valor de retorno de la función interna. Pero quiero crear closedF usando una declaración de función (lo anterior es una expresión de función) para que se defina en el momento del análisis. Es decir.

function closedF()
{
    return function(){/* return value */}
}

Pero esto no funciona porque al llamar a closedF(), devuelve la función interna en lugar del valor de retorno de la función interna. Nota: con la declaración anterior podría usar closedF()(), pero eso es poco elegante.

¿Es posible?

PD. Como suele ser el caso, hay muchas maneras de resolver mi problema de programación particular, pero en realidad quiero que alguien me muestre que las funciones cerradas no son funciones de "ciudadano de segunda clase" en JS.

4
Jeff 8 jul. 2011 a las 23:59

4 respuestas

La mejor respuesta

Su problema no tiene necesariamente nada que ver con la expresión de función vs declaración de función.

En los dos casos que mostró, no obtiene el valor de retorno de la función interna.

podría obtenerlo simplemente llamando a la función interna y devolver su valor:

function closedF() {
    return (function(){
        /* return value */
    }()); // <- calling the inner function here
}

La desventaja es que la función interna siempre se definirá de nuevo cuando se llame a la función externa. Puede evitar esto almacenando en caché la función interna como una propiedad de la función externa:

function closedF() {
    var func = closedF.__func ||  (closedF.__func = function(){
        /* return value */
    });
    return func();
}

Sin embargo, esto podría ser más confuso que útil.

Es más fácil ejecutar la función externa inmediatamente y asignar la función devuelta a una variable, como @ James Long muestra en su respuesta.

Actualización:

También puedes hacer esto:

(function() {
    window.closedF = function() {

    };
}());

Aunque ambas son expresiones de función

3
Community 23 may. 2017 a las 12:19

Te refieres a algo como esto:

function closedF() {
    return function () {
    }
}

Sí, eso es perfectamente aceptable.

Editar : leyendo los comentarios, creo que necesita una función anónima autoejecutable:

var closedF = (function () {
    return function () {
    };
}());

Esto creará una función que simplemente se puede ejecutar llamando closedF(), pero no sé si es posible como una declaración.

1
James Long 8 jul. 2011 a las 20:10

¿Consideró pasar una función como parámetro?

function closedF(fn){
    return fn;
}

Y para usarlo:

var fnParam = function(){...};
...
closedF(fnParam);
1
Mic 8 jul. 2011 a las 20:10

Esto no es posible La única forma de obtener una función dentro de un cierre es ejecutar realmente la función de ajuste que, por supuesto, no puede suceder durante la compilación.

El código que realmente estás buscando es:

var closedF = function(){
    return function(){
       // do stuff
    }
}(); // <-- note the (), which immediately calls the outer function

En última instancia, ni siquiera hay un caso de uso válido para lo que está pidiendo. El objetivo de un cierre es que puede obtener referencias a variables externas pasadas durante la ejecución del programa que están disponibles para una función específica. Si está intentando hacer esto durante la compilación, ya tiene acceso a todo lo que está tratando de obtener ya que todavía no se ha ejecutado ningún coe. Por lo tanto, no hay necesidad de un cierre.

Si publica exactamente lo que está tratando de hacer, puede haber otra solución.

2
Mark Kahn 8 jul. 2011 a las 20:40