I've recently started wrapping the inside of my recursive functions to protect them against renaming/passing:
For instance, say you have:
let factorial = n => {
if (n == 1) return 1;
return n * factorial(n-1);
}
What if this happens:
let recursiveFunc = factorial;
factorial = 1;
recursiveFunc(5) // doesn't work
recursiveFunc refers to the original function, but, because the original
function calls factorial, which got redefined, it no longer works.
Even if you think this specific scenario is unlikely, passing around functions is pretty commonplace in JS-land, and, who knows, maybe the function got imported with a different name, or you received the function as a member of an object.
A solution. Do the recursion inside the function:
let factorial = n => {
const factorial = n => {
if (n == 1) return 1;
return n * factorial(n-1);
}
return factorial(n);
}
let recursiveFunc = factorial;
factorial = 1;
recursiveFunc(5) // works!
FWIW, this is often how things are done in Haskell when recursion is needed (quite often).