階乗関数(factorial)
let factorial = (n) => {
if (n === 0) return 1;
return n * factorial(n - 1);
};
console.log(factorial(5)); // 120
計算イメージ
5 * (4 * (3 * (2 * (1 * 1))))
// 5 * (func4 * (func3 * (func2 * (func1 * 1))))
解説
factorial(n - 1) で関数があると計算結果がまだわからない
だから
計算をきちんとできるまで、計算を「待機」させる
それが以下
↓
5 * (4 * (3 * (2 * (1 * 1))))
// 5 * (func4 * (func3 * (func2 * (func1 * 1))))
その後
深いところから計算していく
その結果が1つのreturnして、変数に代入される
全体イメージ
関数が書き換わるのではなく、呼び出しごとに n が違う実行環境が積み重なる
以下はイメージ
let factorial = (n) => {
if (n === 0) return 1;
return n * factorial(n - 1);
};
console.log(factorial(5));
↓ 5の時
let factorial = (5) => {
if (n === 0) return 1;
return 5 * factorial(5 - 1); // 関数があってまだ計算できないので待機
};
console.log(factorial(5));
↓ 3の時
let factorial = (3) => {
if (n === 0) return 1;
return 3 * factorial(3 - 1); // 関数があってまだ計算できないので待機
};
↓ 2の時
let factorial = (2) => {
if (n === 0) return 1;
return 2 * factorial(2 - 1); // 関数があってまだ計算できないので待機
};
↓ 1の時
let factorial = (1) => {
if (n === 0) return 1;
return 1 * factorial(1 - 1); // 関数があってまだ計算できないので待機
};
↓ 0の時
let factorial = (0) => {
if (0 === 0) return 1;
};
↓ 計算
return 5 * (4 * (3 * (2 * (1 * 1))))
// 5 * (func4 * (func3 * (func2 * (func1 * 1))))
let factorial = return 5 * (4 * (3 * (2 * (1 * 1))));
console.log(factorial);