Переполнение стека после 15 рекурсий с функцией класса Javascript - PullRequest
0 голосов
/ 08 октября 2009

У меня есть следующий пример кода, чтобы проиллюстрировать мою точку зрения. Когда я загружаю это в IE8 в Vista, я получаю ошибку «Переполнение стека в строке: 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>

Ответы [ 2 ]

7 голосов
/ 08 октября 2009

Для вашего рекурсивного оператора нет завершающего условия, поэтому оно будет выполняться вечно.

Похоже, что вы хотите ...


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

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

            alert('done');
1 голос
/ 09 октября 2009

Хорошо, вот еще немного понимания проблемы, с которой я столкнулся. После возвращения и исправления того, что я считал проблемой моего приложения, у меня все еще была проблема. Часть, которая заставила меня заняться этой проблемой, заключалась в том, что, если я повторю только 14 раз, она успешно завершится.

Сначала я выполнял исходный код в HTA, а не в Internet Explorer. Я пишу редактор кода на основе VIM, похожий на FCKEditor.

Во-вторых, структура моего кода следующая:

-HTA

- EditorClass

--- DivManagerClass

---- KeyBindingClass

В моем KeyBindingClass у меня была кодовая база, подобная предоставленному примеру (за исключением того, что у него есть условие завершения)

В моем KeyBindingClass у меня есть свойство повторителя, которое будет повторять последнее нажатие клавиши N раз, если был нажат числовой модификатор. Для тех, кто не знает, нажатие клавиш «3» и «x» в визуальном режиме в vim удалит три символа.

Все работало нормально, пока я не использовал числовой модификатор больше 14.

Я продолжал пытаться воспроизвести эту проблему с помощью небольшого тестового набора и не смог. Мне удалось набрать до 3000 в базовом тестовом сборе. Поэтому я начал воссоздавать сценарий как мог. Сначала я переместил вызов метода recurse в другой класс / метод. Это ограничило мой стек вызовов где-то около 1600 (почти половина стека просто исчезла).

Затем я добавил jQuery в микс и переместил вызов метода ParentClass.recurse в событие привязки клавиш внутри обработчика jquery document.onready. Это уменьшило мой стек вызовов до 1300.

Затем я переместил свой код в HTA, который снова сократил мой стек вызовов пополам! После того, как я подражал своей кодовой базе, как мог, и так быстро, как мог, я достиг стека вызовов около 515.

После некоторых исследований я обнаружил, что IE использует доступное пространство памяти для определения размера стека вызовов. Я предполагаю, что HTA немного более строг в этом отношении. Я не понял, какой другой фактор ограничил мое приложение таким низким стэком вызовов, учитывая структуру класса, но проблема заключается именно в структуре кода.

Я могу поместить свой базовый рекурсивный тест в тег сценария выполнения верхнего уровня и получить около 1473 вызовов до достижения переполнения стека.

Я все еще могу использовать очередь функций для решения моей проблемы, но я просто хотел, чтобы другие знали, что A. Я бы не стал публиковать такую ​​простую проблему в Stack Overflow, а B. что на ваш предел стека вызовов может быть оказано значительное влияние. структурами классов, окружающими функции, даже если они не являются отдельными уровнями того, что вы обычно рассматриваете в стеке функций.

...