Reputation: 1147
function fact(n){
if(n ==1){
return 1
} else{
console.log(fact(n-1))
return n*fact(n-1)
}
}
Above is he snippet of the code.
This is the result of debugging recursive factorial code. I don't understand how these 1s are printed, except one last 1 which is returned from the if block.
It would be great if anyone can explain the debugging of this program.
Upvotes: 1
Views: 1237
Reputation: 386634
If you like to see what a recursive function is doing, I suggest to use the following pattern to get a valid view of the calling order of the recursion.
Add a level variable, where the depth is counted and maintained.
Use two outputs, one at the beginning of the function and one directly before the return takes place.
Do not call the recursion at the place where you make an output, because this calls the resursion and later on return it calls the recursion again. This leads to more recusions than necessary and looks more complicated than it should be. Take for getting a result of the following recursion a variable and use it for output.
What you get, with this in mind, is the following, the first column denotes the level or depth of the recursion and the second in the first half the funcltion call with the value for n
and in the second half the return value.
Same level denotes the same function, which is not ended until the function returns (with or without an explicit value).
Here, the function on level 0
waits for the return value of function with level 1
, whereas function with level 2
waits for the result of level 3
, and so on until a function returns a value without calling the function again. Basically the recusion ends with this value and all unterminated functions are the terminated by retuning a value, in this case 1
, 2
, 6
, 24
and the final value 120
.
level pos value type comment ----- --- -------------------- ------------ ---------------------------- 0 in 5 n wait for result of level 1 1 in 4 n wait for level 2 2 in 3 n wait for level 3 3 in 2 n wait for level 4 4 in 1 n deepest level 4 out 1 return value terminate level 4 3 out 2 return value terminate level 3 2 out 6 return value terminate level 2 1 out 24 return value terminate level 1 0 out 120 return value teminate return final result
function fact(n, level) {
var returnValue;
level = level || 0;
console.log(level, 'in', n);
if (n == 1) {
console.log(level, 'out', 1);
return 1;
} else {
returnValue = n * fact(n - 1, level + 1);
console.log(level, 'out', returnValue);
return returnValue;
}
}
console.log(fact(5));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 5
Reputation: 1492
This is a strange question .. i wanted to write this as a comment but i thought maybe it is easier to read as answer. The one gets printed (as in @Rickard answer) because your base condition returns 1, and you print the fact(n-1).
Anyways I think it is a big mistake that your log actually calls the function again .. and it doesnt help at all! .. what would be more appropriate is that you do this
var result = n*fact(n-1);
console.log('n: ' + n + ', result: ' + result);
return result;
Then the output would make more sense:
n: 2, result: 2
n: 3, result: 6
n: 4, result: 24
n: 5, result: 120
Upvotes: 1
Reputation: 40852
You call fact(n - 1)
twice in your code, once for the debugging (console.log
) and once for its original purpose, that the reasone why you get duplicate values in your debugging output.
To get the correct output you have to save the result of fact(n - 1)
in a variable and use that variable for the debug output and the expression.
function fact(n) {
if (n == 1) {
return 1
} else {
var f = fact(n - 1)
console.log(f)
return n * f
}
}
fact(5)
Upvotes: 0
Reputation: 7591
Put debugger;
before if(n ==1){
and step through it in the debugger in the console, and you will notice why.
In short. You return value 1 to console.log(fact(n-1))
.
Upvotes: 0