Calling a JavaScript Function Recursively

Calling a javascript function recursively

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.

Recursive calls between two functions

So there are a number of ways you can get around this problem & I'd honestly say that it may depend on what you consider important, i.e. it may depend on your style of coding & what preferences you have.



Hoisting

A simple enough technique to use, feel free to read up more on MDN, but in a nutshell hoisting is where you declare a variable towards the start of the file, then use it at some later point. But with functions specifically all you need to do to make use of this concept is define them as traditional functions. The idea being that when you define a function using the keyword function, the function essentially gets defined before other variables within the scope.

Here's a little example:

test();

function test() {
console.log("Hello! :)")
}

JS Recursive function call

() after function name invoke's the function. So as button.addEventListener('click', once()); you are bind the return value of once() method which is undefined.

And since once() is called recursively without any break statement, you are getting the InternalError: too much recursion.

You should pass the function reference.

button.addEventListener('click', once); 

For Additional Info:

Pointer Vs Delegates

How can I recursively stringify a javascript function which calls other scoped functions?

What I ended up rolling with was inspired by @CertainPerformance's answer.

The trick is to build a function which defines all the child callee functions. Then you have everything you need to stringify the parent function.

Note: to allow for imported callee functions from other files, I decided to programmatically build a string with the callee definitions rather than defining them originally in the same scope.

The code:

    // original function definitions (could be in another file)    let bar = () => { alert(1) }    let foo = () => { bar() }

const allCallees = [ bar, foo ]
// build string of callee definitions const calleeDefinitions = allCallees.reduce( (definitionsString, callee) => { return `${definitionsString} \n const ${callee.name} = ${callee.toString()};`; }, "", );
// wrap the definitions in a function that calls foo const fooString = `() => { ${calleeDefinitions} \n return foo(); \n }`;
console.log(fooString); /** * fooString looks like this: * `() => { * const bar = () => { alert(1) }; * const foo = () => { bar() }; * return foo(); * }` **/
// in new context & scope const evaluatedFoo = new Function(' return (' + fooString + ').apply(null, arguments)');
// works as expected evaluatedFoo();

javascript: recursive anonymous function?

You can give the function a name, even when you're creating the function as a value and not a "function declaration" statement. In other words:

(function foo() { foo(); })();

is a stack-blowing recursive function. Now, that said, you probably don't may not want to do this in general because there are some weird problems with various implementations of Javascript. (note — that's a fairly old comment; some/many/all of the problems described in Kangax's blog post may be fixed in more modern browsers.)

When you give a name like that, the name is not visible outside the function (well, it's not supposed to be; that's one of the weirdnesses). It's like "letrec" in Lisp.

As for arguments.callee, that's disallowed in "strict" mode and generally is considered a bad thing, because it makes some optimizations hard. It's also much slower than one might expect.

edit — If you want to have the effect of an "anonymous" function that can call itself, you can do something like this (assuming you're passing the function as a callback or something like that):

asyncThingWithCallback(params, (function() {
function recursive() {
if (timeToStop())
return whatever();
recursive(moreWork);
}
return recursive;
})());

What that does is define a function with a nice, safe, not-broken-in-IE function declaration statement, creating a local function whose name will not pollute the global namespace. The wrapper (truly anonymous) function just returns that local function.

Call asynchronous function recursively

The question is whether the stack is filling with calls and may cause
stackoverflow at some point?

No. If asyncBar() calls the callback it is passed asynchronously, then there is no stack build-up.

In your code:

function foo() {
asyncBar(foo);
}

here is what is happening, step-by-step:

  1. First foo() is called.
  2. This then calls asyncBar(foo).
  3. Because asyncBar is asynchronous, that means it starts an asynchronous operation (let's suppose it is an http GET, but any async operation will do). That asynchronous operation is initiated, but then asyncBar() immediately returns.
  4. That initial call to foo() returns and the stack is completely unwound. There is no foo() on the stack any more.
  5. Any code after the call to foo() continues to run until it is done and returns back to the event loop.
  6. Meanwhile the asynchronous operation finishes some time in the future. That places a call to your callback in the event queue.
  7. When the JS engine is done executing other Javascript (which means the stack is completely empty), it pulls that event out of the event queue and calls the callback.
  8. In this case, the callback function is foo so it calls that function and starts the cycle all over again, right back to step 2.

There is no stack build-up. The key is that asynchronous callbacks are called sometime later, after the current stack has finished, unwound and returned back to the system.

Recursive function still being called even when the condition for the while loop is not met

The while loop isn't necessary here for a recursive solution, simply return the function with the page incremented by one. You have defined a base case if (page === pagecount) which is good, but you need to stop the recursion with a return statement at some point. I removed the while loop and updated your code.

You can choose to modify the return results as you see fit, that is whether you want to return nothing or return some meaningful data when the recursion encounters the base case.

let pagecount = 3;
let i = 1;
const testfunc = (page) => {
console.log("apicalled with page", page);
console.log("page", page, "pagecount", pagecount);

// this is the recursion base case
if (page === pagecount) {
console.log("condition fulfilled", page !== pagecount);
return
}

return testfunc(page+1)
}

testfunc(i);

From a cloud function: how to call JavaScript function that is recursive?

It turns out that testrecur() needs to return a promise so that the caller, in this case, testrecursion() will wait for testrecur() to complete before starting the next chain in the promise. The actual code is available at How to return a value from a regular javascript function that contains a promise chain?

By the way, the recursion code in this question is correct because the recursion is happening correctly. We just need to tie the promises in sequence so each recursive call can have the opportunity to execute completely before the calling function completes.

Recursive function calling in JavaScript

Function calls are just more expensive than a simple loop due to all the overhead of changing the stack and setting up a new context and so on. In order for recursion to be very efficient, a language has to support some form of tail-call elimination, which basically means transforming certain kinds of recursive functions into loops. Functional languages like OCaml, Haskell and Scheme do this, but no JavaScript implementation I'm aware of does so (it would only be marginally useful unless they all did, so maybe we have a dining philosophers problem).



Related Topics



Leave a reply



Submit