Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make this javascript work?

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 ?

like image 948
Marc Antoine Avatar asked Jan 10 '12 22:01

Marc Antoine


People also ask

How this works in JavaScript?

In JavaScript, the this keyword refers to an object. Which object depends on how this is being invoked (used or called). The this keyword refers to different objects depending on how it is used: In an object method, this refers to the object.

How do I run a JavaScript?

To execute JavaScript in a browser you have two options — either put it inside a script element anywhere inside an HTML document, or put it inside an external JavaScript file (with a . js extension) and then reference that file inside the HTML document using an empty script element with a src attribute.


2 Answers

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

like image 176
Rob W Avatar answered Sep 29 '22 09:09

Rob W


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)

like image 35
Jason S Avatar answered Sep 29 '22 07:09

Jason S