Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a javascript function recursively

I can create a recursive function in a variable like so:

/* Count down to 0 recursively.  */ var functionHolder = function (counter) {     output(counter);     if (counter > 0) {         functionHolder(counter-1);     } } 

With this, functionHolder(3); would output 3 2 1 0. Let's say I did the following:

var copyFunction = functionHolder; 

copyFunction(3); would output 3 2 1 0 as above. If I then changed functionHolder as follows:

functionHolder = function(whatever) {     output("Stop counting!"); 

Then functionHolder(3); would give Stop counting!, as expected.

copyFunction(3); now gives 3 Stop counting! as it refers to functionHolder, not the function (which it itself points to). This could be desirable in some circumstances, but is there a way to write the function so that it calls itself rather than the variable that holds it?

That is, is it possible to change only the line functionHolder(counter-1); so that going through all these steps still gives 3 2 1 0 when we call copyFunction(3);? I tried this(counter-1); but that gives me the error this is not a function.

like image 852
Samthere Avatar asked Aug 15 '11 12:08

Samthere


People also ask

Can JavaScript functions be recursive?

A function that calls itself is called a recursive function. The syntax for recursive function is: function recurse() { // function code recurse(); // function code } recurse(); Here, the recurse() function is a recursive function.

How do you call a function recursively?

Recursion using mutual function call: (Indirect way) Indirect calling. Though least practical, a function [funA()] can call another function [funB()] which in turn calls [funA()] the former function. In this case, both the functions should have the base case.

What does it mean to call a function recursively?

A recursive function is a function in code that refers to itself for execution. Recursive functions can be simple or elaborate. They allow for more efficient code writing, for instance, in the listing or compiling of sets of numbers, strings or other variables through a single reiterated process.

How do you call a recursive function in TypeScript?

Basically there are two ways to code recursive functions in TypeScript: First by directly calling the function from within itself and. Second by using an indirect call.


1 Answers

Using Named Function Expressions:

You can give a function expression a name that is actually private and is only visible from inside of the function ifself:

var factorial = function myself (n) {     if (n <= 1) {         return 1;     }     return n * myself(n-1); } typeof myself === 'undefined' 

Here myself is visible only inside of the function itself.

You can use this private name to call the function recursively.

See 13. Function Definition of the ECMAScript 5 spec:

The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

Please note that Internet Explorer up to version 8 doesn't behave correctly as the name is actually visible in the enclosing variable environment, and it references a duplicate of the actual function (see patrick dw's comment below).

Using arguments.callee:

Alternatively you could use arguments.callee to refer to the current function:

var factorial = function (n) {     if (n <= 1) {         return 1;     }     return n * arguments.callee(n-1); } 

The 5th edition of ECMAScript forbids use of arguments.callee() in strict mode, however:

(From MDN): In normal code arguments.callee refers to the enclosing function. This use case is weak: simply name the enclosing function! Moreover, arguments.callee substantially hinders optimizations like inlining functions, because it must be made possible to provide a reference to the un-inlined function if arguments.callee is accessed. arguments.callee for strict mode functions is a non-deletable property which throws when set or retrieved.

like image 52
Arnaud Le Blanc Avatar answered Sep 28 '22 06:09

Arnaud Le Blanc