Since countup() is fully divided by an if statement that depends on n, let's first see what exectutes for different vales of n.
To make it a lot easier to follow, we'll append our current n to countArray's variable name:
n == 5:
const countArray5 = countup(4);
countArray5.push(5);
return countArray5;
⋮
n == 1:
const countArray1 = countup(0);
countArray1.push(1);
return countArray1;
n == 0:
return [];
Now let's sequentially expand each inner call to countup(n):
countup(5) {
const countArray5 = countup(4);
countArray5.push(5);
return countArray5;
}
countup(5) {
const countArray5 = countup(4) {
const countArray4 = countup(3);
countArray4.push(4);
return countArray4;
};
countArray5.push(5);
return countArray5;
}
Expanding until countup(0):
countup(5) {
const countArray5 = countup(4) {
const countArray4 = countup(3) {
const countArray3 = countup(2) {
const countArray2 = countup(1) {
const countArray1 = countup(0) // countup(0) returns [] so countArray1 = [];
countArray1.push(1); // Then push '1' to countArray1;
return countArray1; // Return [1] at counterArray2 = countup(1) above
};
countArray2.push(2); // countArray2 was [1], now push '2' to make it [1,2]
return countArray2; // Return [1,2] at countArray3 = countup(2) above
};
countArray3.push(3); // Push '3' to countArray3 => [1,2,3]
return countArray3; // return [1,2,3] at countArray4 = countup(3)
};
countArray4.push(4); // Push '4' to countArray4 => [1,2,3,4]
return countArray4; // Return [1,2,3,4] at countArray5 = countup(4)
};
countArray5.push(5); // Push '5' to countArray5 => [1,2,3,4,5]
return countArray5; // countup(5) returns [1,2,3,4,5]
}