Sure, let’s see if we can dive into what this is doing. A few key parts to recursion we need to define, to start:
- What is our exit condition? At what point have we called our function deep enough, and can begin returning back up the chain?
- What is our recursive behavior? What do we do, each time we call the function?
- How are we approaching that exit condition? Somehow, we need to be changing each call to our function, to approach our exit.
In this case, our exit condition is if(endNum-startNum===0)
. so at each iteration, we need to either increment startNum
or decrement endNum
. They need to eventually be the same number, otherwise we will be looping forever. So our exit condition sounds like “when startNum === endNum
, we can start returning everything.”
Now, what’s our recursive behavior? What do we do each time? We take whatever is stored in the var numbers
recursive call, we push a value onto it, and we return
that numbers
variable.
And how are we approaching that exit condition (remember, we want startNum===endNum
eventually)? By reducing endNum
on each iteration, each time we call rangeOfNumbers(...)
, we have reduced the gap between the two by one.
At our innermost call, startNum===endNum
, and we begin returning.
So let’s unpack what that’s actually doing.
We call our original function, say rangeOfNumbers(1, 4)
. That checks if 1===4
and… nope. So it goes to the else
side, and says var numbers = rangeOfNumbers(1, 3)
. Again with the exit check, and again, no exit.
Eventually, we get to var numbers = rangeOfNumbers(1, 1)
. At this point, we check our exit condition, is 1===1
? It is indeed. So THIS time, we take the if
branch. We return [1]
, which is passed to the next function out.
The next function out was the call to rangeOfNumbers(1,2)
, and our returned [1]
is being stored in the var numbers
- so now var numbers=[1]
. At that point, we numbers.push(2)
, as endNum===2
here, and then we return
[1,2]` to the next function out.
That gets passed to the rangeOfNumbers(1,3)
's else branch, where we were assigning something to var numbers = ...
. In this case, we’ve set numbers=[1,2]
, as that was the returned value. And we’re pushing onto that, and returning [1,2,3]
.
And we do that until we reach our ultimate final call, where we called our function (not where it called itself). And it returns to us [1,2,3,4]
.