5

I'm trying to make a recursive anonymous function.

Here is the function :

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

I know "this" is the window object. Is there a way to call the function ?

Daniel Li
  • 14,976
  • 6
  • 43
  • 60
Marc Antoine
  • 51
  • 1
  • 2
  • 1
    The **best** thing to do is to have it not be an anonymous function, but instead a function defined with a function declaration statement. – Pointy Jan 10 '12 at 22:35

3 Answers3

12

The arguments.callee property can be used.

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

Another method to achieve the same functionality is by naming function. Outside the scope, the name will not be available:

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


Note that use of the arguments.callee property is forbidden in strict mode:
"use strict";
(function(){arguments.callee})();

throws:

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

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • 4
    Note that `arguments.callee` is deprecated (and quite vociferously, if you've ever heard it spoken of at a JavaScript conference), and won't be supported in the future. It's also pretty slow. Also, naming your functions when they're defined with a function *expression* (as opposed to a declaration statement) is risky because [browsers sometimes do weird things.](http://kangax.github.com/nfe/) – Pointy Jan 10 '12 at 22:34
  • Didn't expect to learn a new word on this thread. "Vociferously" is fantastic. – Dylan Valade Jan 19 '15 at 02:50
1

You give a name to anonymous function, here I give it a name "_", although it is named, but it is still anonymous.

(function _( i ) {
  console.log(i);
  if (i < 5){ _(i + 1); }
})(0);
Fred Yang
  • 2,521
  • 3
  • 21
  • 29
1

Ah... the functional forms of recursion.... [[[flashback to comp sci class]]]

You could use a helper function:

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

(which returns 720; this is the factorial function, the canonical example of recursion)

This could in turn be anonymized:

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

or specialized to functions of one argument, to avoid apply and arguments:

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

(both of which also return 720)

This trick of using a helper function allows your function to receive itself as its first argument, and thereby call itself.

To adapt your example:

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

which works as expected in Firebug (logs 0,1,2,3,4,5 to console)

Jason S
  • 184,598
  • 164
  • 608
  • 970