たまにですが「Uncaught RangeError: Maximum call stack size exceeded」とエラーが出るときがあります。
コールスタックのサイズが最大値を超えたよ!と怒られているわけですが、そもそもコールスタックとはなんなのでしょうか。
コールスタックとは
ドキュメントCall stack (コールスタック) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN
を見たところ、
- どの関数が呼び出されているか
- どの順番で関数が呼び出されたか
の2つを保存しておく仕組みのことを「コールスタック」というようです。
要は、呼び出された関数を実行順に記憶してくれるのが「コールスタック」です。
「コールスタック」なので、実行される関数を後入れ先出し法で保存していきます。
例えば、関数Aの中で関数Bを実行するようなプログラムを書いたとします。
function A(){ console.log('A Start'); let message = B(); console.log(message); console.log('A finish'); } function B(){ console.log('B Start'); return "B finish"; } A();
プログラムを実行すると、関数Aが一番最初に呼び出されます。
このとき、コールスタックに関数Aが追加されます。
コールスタック = [関数A]
次に関数Aの中で関数Bが呼び出されます。
すると、コールスタックの先頭に関数Bが追加されます。
コールスタック = [関数B, 関数A]
Bが先頭に追加されるので、インタプリタはAの処理を中断してBの処理に入ります。
そしてBが終わったあと、コールスタックからBを取り除き、
コールスタック = [関数A]
再びAが先頭に来るので、Aの処理に入ります。
こうすることで関数がバラバラに実行されることを防いでいるというわけです。
スタックオーバーフロー
コールスタックに貯めて置ける関数には上限があります。
冒頭で紹介したこのエラーですが、
Uncaught RangeError: Maximum call stack size exceeded
これはコールスタックが最大サイズを超えたということで「スタックオーバーフロー」といいます。
ブラウザごとにコールスタックの最大値は違います。
各ブラウザごとのコールスタックサイズの比較はこちらの記事に書いてありました。
コールスタック・サイズの最大は? どこまで関数は深く呼び出せるのか? (JavaScript) - Qiita
ブラウザゲームを作る時に、アニメーションなんかでよくオーバーフローするので気を付けましょう。