0

私の要点を説明するために、次のコードサンプルがあります。これを Vista の IE8 にロードすると、「Stack Overfow at line:16」というエラーが表示されます。

トップレベルの関数 (testClass オブジェクトの外部) を使用して再帰すると、スタック オーバーフローなしで何百万回も再帰できます。

なぜこうなった?最終的に、再帰を使用する代わりに Function Que を実装しましたが、意味がわかりません。原因を理解したいと思います。

-- コード --

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
<html>
    <head>
        <title>Recusion Test</title>
        <body>
        </body>

        <script type="text/javascript">

            function testClass() {
                this.x = 15;
                this.recurse = function() {
                    this.x--;
                    this.recurse();
                }
            }

            var wtf = new testClass();
                wtf.recurse();

            alert('done');
        </script>
    </head>
</html>
4

2 に答える 2

7

再帰ステートメントには終了条件がないため、永久に実行されます。

あなたが欲しいようです...


            function testClass() {
                this.x = 15;
                this.recurse = function() {
                    if (this.x--)
                        this.recurse();
                }
            }

            var wtf = new testClass();
                wtf.recurse();

            alert('done');
于 2009-10-08T18:38:13.430 に答える
1

わかりました、ここで私が抱えていた問題についてさらに洞察があります。戻って、自分のアプリケーションの問題と思われるものを修正した後も、まだ問題がありました。私がこの問題を追求するようになったのは、14 回再帰するだけで正常に完了するということでした。

まず、元のコードを Internet Explorer ではなく HTA で実行していました。FCKEditor に似た VIM ベースのコード エディターを作成しています。

次に、私のコードの構造は次のとおりです。

-HTA

--EditorClass

---DivManagerClass

----KeyBindingClass

私の KeyBindingClass には、提供された例に似たコードベースがありました (終了条件があることを除いて)

私の KeyBindingClass には、数値修飾子が押された場合に最後のキーストロークを N 回繰り返すリピーター プロパティがあります。vimのビジュアルモードでキー「3」と「x」を押すと3文字が削除されることを知らない人のために。

14 より大きい数値修飾子を使用するまでは、すべて正常に機能していました。

小さなテスト ハーネスでこの問題を再現しようとし続けましたが、できませんでした。基本的なテスト ハーネスで 3000 まで再帰できました。そこで、できる限りシナリオを再現し始めました。まず、再帰メソッドの呼び出しを別のクラス/メソッドに移動しました。これにより、呼び出しスタックが 1600 前後に制限されました (スタックのほぼ半分が消えました)。

次に、jQuery をミックスに追加し、ParentClass.recurse メソッドの呼び出しを document.onready jquery ハンドラー内のキーバインディング イベントに移動しました。これにより、コールスタックが約 1300 に減少しました。

次に、コードを HTA に移動したところ、コール スタックが再び半分になりました。コードベースを可能な限り模倣した後、可能な限り迅速に、約 515 のコールスタックに到達しました。

いくつかの再検索を行った後、IE が使用可能なメモリ領域を使用してコールスタック サイズを決定することがわかりました。その点で、HTA はもう少し厳密であると思います。クラス構造を考えると、他のどの要因がアプリケーションのコールスタックを非常に低く制限しているのかはわかりませんが、問題なのはコード構造であることは間違いありません。

基本的な再帰テストを最上位の実行スクリプト タグに配置すると、スタック オーバーフローに達する前に約 1473 回の呼び出しを取得できます。

関数キューを使用して問題を解決することはできますが、A. このような単純な問題を Stack Overflow に投稿しないこと、および B. 呼び出しスタックの制限がクラスによって大きく影響を受ける可能性があることを他の人に知ってもらいたかっただけです。従来関数スタックと見なされていた別のレベルではありませんが、関数を囲む構造です。

于 2009-10-08T21:25:04.793 に答える