2012-01-10 23 views
5

Estoy tratando de hacer una función anónima recursiva.¿Cómo hacer que este javascript funcione?

Aquí es la función:

(function (i) { 
    console.log(i); 
    if (i < 5) this(i + 1) 
})(0) 

Sé que "este" es el objeto de la ventana. ¿Hay alguna manera de llamar a la función?

+1

Lo mejor ** que hacer es que no sea una función anónima, sino una función definida con una declaración de declaración de función. – Pointy

Respuesta

12

Se puede usar la propiedad arguments.callee.

(function(i){console.log(i);if(i<5)arguments.callee(i+1)})(0) 

Otro método para lograr la misma funcionalidad es nombrando la función. Fuera del ámbito, el nombre no estará disponible:

(function tmp(i){console.log(i);if(i<5)tmp(i+1)})(0); //OK, runs well 
alert(typeof tmp); // Undefined 


Tenga en cuenta que el uso de la propiedad arguments.callee está prohibido en modo estricto:

"use strict"; 
(function(){arguments.callee})(); 

lanza:

TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

+1

Gracias! Dormiré más inteligente. –

+4

Tenga en cuenta que 'arguments.callee' está en desuso (y bastante vociferante, si alguna vez lo ha oído hablar en una conferencia de JavaScript), y no será compatible en el futuro. También es bastante lento. Además, nombrar sus funciones cuando están definidas con una función * expresión * (a diferencia de una declaración de declaración) es arriesgado porque [los navegadores a veces hacen cosas raras.] (Http://kangax.github.com/nfe/) – Pointy

+0

No esperaba aprender una palabra nueva en este hilo. "Vociferantemente" es fantástico. –

1

Ah ... las formas funcionales de recursión .... [[[flashback a clase de ciencia ficción]]]

Se podría utilizar una función auxiliar:

function X(f) { return f.apply(this, arguments); } 
X(function(me, n) { return n<=1 ? n : n*me(me,n-1); }, 6); 

(que devuelve 720; esta es la función factorial, el ejemplo canónico de recursión)

Esto podría a su vez ser anónimos:

(function (f) { return f.apply(this, arguments); })(
    function(me, n) { return n<=1 ? n : n*me(me,n-1); }, 
    6); 

o especializada para funciones de un argumento, para evitar apply y arguments:

(function (f,x) { return f(f,x); })(
    function(me, n) { return n<=1 ? n : n*me(me,n-1); }, 
    6); 

(los cuales también devuelven 720)

Este truco de usar una función auxiliar permite que su función reciba su elfo como su primer argumento, y por lo tanto se llama a sí mismo.

adaptar su ejemplo:

(function (f,x) { return f(f,x); })(
    function(me, i) { console.log(i); if (i<5) me(me,i+1); }, 
    0) 

que funciona como se espera en Firebug (0,1,2,3,4,5 registros de consola)

1

le dará un nombre de función anónima, aquí le doy el nombre "_", aunque lleva su nombre, pero sigue siendo anónimo.

(function _(i) { 
    console.log(i); 
    if (i < 5){ _(i + 1); } 
})(0); 
Cuestiones relacionadas