I'll pitch in with my own intuition; the easiest way to understand it is to view it as a call stack. Using this example function:
function RecFunc(n, max) {
let result; // intialize the return variable
if (n < max) {
result = RecFunc(n + 1, max) // the recursion
} else {
result = n; // the exit condition
}
return result;
}
RecFunc(0, 3);
When you call the function, we descend down the stack until it hits the exit condition. Notice that `result` is undefined in the upper levels of the stack; when `n` is equal to `max`, the function is finally able to assign a value to `result` and exit:
| RecFunc
v n: 0, max: 3, result: undefined
| RecFunc
v n: 1, max: 3, result: undefined
| RecFunc
v n: 2, max: 3, result: undefined
| RecFunc
v n: 3, max: 3, result: 3
Now that the exit condition has been met, we go back up the stack, returning the result at each step:
[0] https://github.com/reduxjs/redux/blob/master/src/compose.js