If you enhance the function with a bit of logging it's easy to visualize the recursion depth and the way it descends and ascends into each call:
function log(indentation) {
var args = [' '.repeat(indentation)]
.concat(Array.from(arguments).slice(1));
console.log.apply(null, args);
}
function mystery(n, depth) {
if (n === 0) {
log(depth, 'mystery called with n =', n, 'returning 1');
return 1;
} else {
log(
depth, 'mystery called with n =', n,
'going into recursion: multiplying with mystery(', n - 1, ')'
);
var result = n * mystery(n - 1, depth + 1);
log(
depth, 'mystery called with n =', n,
'returning', result, ' after recursion'
);
return result;
}
}
var initialDepth = 0;
mystery(4, initialDepth);
// Output:
mystery called with n = 4 going into recursion: multiplying with mystery( 3 )
mystery called with n = 3 going into recursion: multiplying with mystery( 2 )
mystery called with n = 2 going into recursion: multiplying with mystery( 1 )
mystery called with n = 1 going into recursion: multiplying with mystery( 0 )
mystery called with n = 0 returning 1
mystery called with n = 1 returning 1 after recursion
mystery called with n = 2 returning 2 after recursion
mystery called with n = 3 returning 6 after recursion
mystery called with n = 4 returning 24 after recursion
mystery(4)->4 * mystery(3)->3 * mystery(2)->2 * mystery(1)->1 * mystery(0)->1=>1 * 2 * 3 * 4(nis just a local variable){...}from a single-statementifbody, then please put it on the same line as theif. It's much too liable to cause confusion otherwise (it's not instantly apparent that the secondreturnisn't inside theifstatemenet).