では前回の「JSON → HTMLリスト変換」を題材に、再帰版とループ版を比較してみましょう。
再帰版(シンプルで直感的)
function jsonToHtml(node) {
let html = `<li>${node.name}`;
if (node.children && node.children.length > 0) {
html += "<ul>";
for (const child of node.children) {
html += jsonToHtml(child); // 再帰で潜る
}
html += "</ul>";
}
html += "</li>";
return html;
}
const htmlList = `<ul>${jsonToHtml(data)}</ul>`;
HTML👉 「子があればもう一度呼ぶ」というルールだけで、ツリー構造を自然に処理できる。
ループ版(スタックを自分で管理)
function jsonToHtmlLoop(root) {
let html = "";
const stack = [{ node: root, depth: 0, state: "enter" }];
while (stack.length > 0) {
const { node, depth, state } = stack.pop();
if (state === "enter") {
html += `<li>${node.name}`;
if (node.children && node.children.length > 0) {
html += "<ul>";
// 子要素を逆順で積む(スタックなので処理順を保つため)
stack.push({ node, depth, state: "exit" });
for (let i = node.children.length - 1; i >= 0; i--) {
stack.push({ node: node.children[i], depth: depth + 1, state: "enter" });
}
} else {
html += "</li>";
}
} else if (state === "exit") {
html += "</ul></li>";
}
}
return `<ul>${html}</ul>`;
}
HTML👉 再帰を使わない場合は「自分でスタックを持ち、入るときと出るときの処理を管理」する必要がある。
✅ 比較まとめ
| 観点 | 再帰版 | ループ版 |
|---|---|---|
| コード量 | 短い | 長い |
| 可読性 | ツリー構造を直感的に表現 | スタック管理が複雑 |
| 柔軟性 | 子がある限り自然に潜れる | 自分で「入る/出る」を制御 |
| 性能 | 呼び出しオーバーヘッドあり | 高速・安全(スタックオーバーフローなし) |
結論
- 再帰版 → 「ツリー構造をそのままコードに落とし込める」ので直感的で読みやすい。
- ループ版 → 「スタックを自分で管理」する分コードは複雑になるが、大量データでも安全に動く。
👉 ここまでで「再帰とループの実装比較」ができました。
次のステップとしては「どの場面で再帰を選び、どの場面でループを選ぶか」という実務的な判断基準を整理してみると、さらに理解が深まります。


