2011-08-05 12 views
22

¿Puedo escribir una función que se devuelva?¿Se puede devolver una función JavaScript?

Estaba leyendo una descripción sobre cierres - see Example 6 - donde una función devolvía una función, por lo que podía llamar al func()(); como JavaScript válido.

así que me preguntaba una función podría volver en sí de tal manera que se puede encadenar a sí misma indefinidamente como esto:

func(arg)(other_arg)()(blah); 

Usando arguments objeto, destinatario de la llamada o la persona que llama?

+0

cuestión relacionada : [Marco de JavaScript FAB en Node.js] (http://stackoverflow.com/questions/3799238) – CMS

+0

http://stackoverflow.com/questions/6084872/an-object-that-returns-an- instancia de sí mismo http://stackoverflow.com/questions/1791793/javascript-function-call-to-itself –

Respuesta

25

Hay 2-3 formas. Una es, como dices, usar arguments.callee. Puede ser que sea la única manera si usted está tratando con una función anónima que no se almacena asignado a una alguna parte variable (que se sepa):

(function() { 
    return arguments.callee; 
})()()()().... ; 

La segunda es utilizar el nombre de la función

function namedFunc() { 
    return namedFunc; 
} 
namedFunc()()()().... ; 

Y el último es usar una función anónima asignada a una variable, pero debe conocer la variable, por lo que en ese caso no veo ninguna razón, por qué no se puede dar un nombre a la función y usar el método arriba

var storedFunc = function() { 
    return storedFunc; 
}; 
storedFunc()()()().... ; 

Todos son funcionalmente idénticos, pero callee es el más simple.

Editar: Y estoy de acuerdo con SLaks; No puedo recomendar que sea

+8

Merece la pena señalar que 'arguments.callee' arroja un error en ES5 Strict http://ejohn.org/blog/ecmascript-5-strict-mode-json-andmore/ –

+1

@abbotto El método 3 funciona bien para mí, pero sí, el método 2 es la forma "correcta" de hacerlo. En cuanto a la desaprobación, tenga en cuenta que esta respuesta tiene 5 años de antigüedad – Flambino

+2

@Flambino, está en lo cierto. Método 1: en general, debería evitarse por completo porque arguments.callee ha quedado obsoleto. Ver: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee Método 2: Esta es la mejor manera de hacer una llamada a función recursiva en JS, porque el la función no es anónima y su nombre aparecerá en los rastros de la pila. – abbotto

11

Sí.
Sólo return arguments.callee;


Sin embargo, es probable que esto resultará en un código muy confuso; No lo recomiendo.

+5

Me gustaría simplemente nombrar la función, en su lugar usando 'arguments.callee' por dos razones: 1 .Las funciones generalmente se optimizan mediante implementaciones; si no se usa el objeto 'arguments', generalmente no se creará (el contexto de ejecución se inicializará más rápido); por supuesto, si la función usa' eval', normalmente puede estar optimizado-. 2. El objeto 'arguments' tenía cambios en el modo estricto de ES5, y la propiedad' arguments.callee' ha sido desautorizada (nuevamente también para problemas de optimización y seguridad), así que básicamente para escribir código * future-proof *, recomendaría a solo nombra la función. :) – CMS

+0

@CMS: ¿Estás seguro de que 'callee' ya no está permitido? Pensé que era 'llamante'. – SLaks

+1

ambos están prohibidos, y el 'que llama' AFAIR en realidad nunca formó parte de la especificación, pero fue compatible con muchas implementaciones, por eso en ES5, para funciones estrictas, tanto 'llamador' como' destinatario' se asignan a una [función de tirador ] (http://es5.github.com/#x13.2.3), vea el * Paso 14 * en [10.6 Arguments Object] (http://es5.github.com/#x10.6) – CMS

1

Hay una manera sencilla de lograr esto haciendo lo siguiente:

let intArr = []; 
function mul(x){ 
    if(!x){ 
     return intArr.reduce((prev, curr) => prev * curr) 
    } 
    intArr.push(x); 
    return mul; 
} 

console.log(mul(2)(4)(2)()); => outputs 16 
0

También es posible sólo para devolver el argumento de la función invocable auto como

console.log((function(a) { return a; })(1)); // returns 1 
Cuestiones relacionadas