JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

JavaScriptにおける再帰関数の仕組みを徹底解説

再帰とは何か

関数が自分自身を呼び出す仕組みを「再帰」と呼びます。JavaScriptでも他の多くのプログラミング言語と同様に、再帰関数を自然に記述できます。再帰は、階乗の計算や木構造・ネストされたデータの探索など、同じ処理を繰り返しながら問題を段階的に縮小していきたい場面で特に有効な手法です。

再帰関数に必要な2つの要素

正しく動作する再帰関数には、次の2つの要素が不可欠です。

  • ベースケース(終了条件): 再帰呼び出しを停止するための条件。これがないと関数は無限に呼び出され続け、スタックオーバーフローが発生します。
  • 再帰ケース: 自分自身を、より小さな引数で呼び出す部分。元の問題を少しずつ小さくしながらベースケースへ向かいます。

例:階乗を求める再帰関数

以下は、関数が自分自身を呼び出して5の階乗(5!)を計算するシンプルな例です。

<html>
  <body>
    <script>
      function displayFact(value) {
        if (value < 0) {
          return -1;
        }
        // 0の階乗は1と定義される
        else if (value == 0) {
          return 1;
        } else {
          return (value * displayFact(value - 1));
        }
      }
      var res = displayFact(5);
      document.write("5の階乗 = " + res);
    </script>
  </body>
</html>

コードの解説

この displayFact 関数は、引数の値に応じて次のように分岐します。

  • 引数が 0未満 の場合は -1 を返し、不正な入力に対応します。
  • 引数が 0 の場合は 1 を返します。数学的に「0! = 1」と定義されているためで、これがベースケースとなります。
  • それ以外の場合は value * displayFact(value - 1) を返し、自分自身を1つ小さい値で呼び出します。これが再帰ケースです。

実行結果

5の階乗 = 120

再帰呼び出しの流れ

displayFact(5) の呼び出しは、内部で次のように展開されていきます。

displayFact(5) → 5 × displayFact(4)
displayFact(4) → 4 × displayFact(3)
displayFact(3) → 3 × displayFact(2)
displayFact(2) → 2 × displayFact(1)
displayFact(1) → 1 × displayFact(0)
displayFact(0) → 1 ※ここでベースケースに到達

各呼び出しの戻り値が順に掛け合わされ、最終的に 5 × 4 × 3 × 2 × 1 = 120 という結果が得られます。

まとめ

再帰関数は、大きな問題をより小さな単位に分解して解決するための強力なテクニックです。実装の際は、必ず終了条件(ベースケース)を明確に定義し、再帰が深くなりすぎてスタックオーバーフローを起こさないよう注意しましょう。条件さえ適切に設計すれば、ループ処理よりも簡潔で読みやすいコードを書けることがあります。

  1. 【初心者向け】Pythonのisinstance()関数の仕組みと使い方をわかりやすく解説

    複数の親クラスからクラスを継承する(多重継承) Pythonでは、以下のように1つのクラスを複数の親クラスから派生させる「多重継承」が可能です。 class A: # クラスAの定義 ... class B: # クラスBの定義 ... class C(A, B): # AとBの両方を継承するサブクラス ... 上記の例では、クラスCはクラスAとクラスBの両方の性質を受け継いだサブクラスになります。このような継承関係が複雑になると、「あるオブジェクトがどのクラスに属しているのか」を確認したくなる場面が出てきます。 isinstance()関数でクラスとインスタン

  2. Pythonのissubclass()関数とは?使い方と継承関係の判定方法を解説

    issubclass()関数とはPythonでは、1つのクラスを複数の親クラス(基底クラス)から派生させることができます。これを「多重継承」と呼びます。以下のように記述することで、クラスCはクラスAとクラスBの両方を親として持つことができます。class A: # クラスAの定義 ...class B: # クラスBの定義 ...class C(A, B): # AとBのサブクラス ...issubclass()関数の基本的な使い方2つのクラス間に継承関係があるかどうかを確認したい場合には、組み込み関数であるissubclass()を使用します。書式は