Косвенная рекурсия в Javascript
Пытаюсь разобраться в рекурсии. Почему когда я пишу так:
<script type="text/javascript"> function recursMe(param) { if (param < 0) { //base case return -1; } else { //some code here recursMe(param); } } recursMe(10); </script> или так (используя косвенную рекурсию): <script type="text/javascript"> function recursMe(param) { if (param < 0) { //base case return -1; } else { //some code here //recursMe(param); recursMe2(param); } } function recursMe2(param) { recursMe(param); } recursMe(10); </script> во всех браузерах я имею ошибку примерно такого характера: Хром: Uncaught RangeError: Maximum call stack size exceeded ie: Stack overflow at line:135 Когда я делаю косвенную рекурсию через setTimeout() так: <script type="text/javascript"> function recursMe(param) { if (param < 0) { //base case return -1; } else { //some code here setTimeout("recursMe(" + param + ")", 1); } } recursMe(10); </script> браузеры не выдают ошибку, хотя происходит та же ситуация: функция recursMe() вызывается много раз подряд. Почему так происходит? |
hrundel, http://css-live.ru/javascript/javasc...rekursiya.html - не самая хорошая статья.
Что проиходит в первом коде, приведенном Вами? Подсказка: Цитата:
Лично я бы не стал разбирать рекурсию на таких отвлеченных примерах. Для начала попробуйте зарыться в DOM. |
Цитата:
там же ошибка переполнения стека Stack overflow at line:135 с setTimiout у Вас нерекурсивное обращение к функции |
Цитата:
Что за глобальный контекст у setTimeout()? Как он может влиять на переполнение стека? |
Цитата:
|
Цитата:
В чем смысл рекурсии-когда функция вызывает саму себя то текущее состояние записывается в стек -потому что потом должны быть выполнены команды которые стоят после операции вызова Это обычно например обход дерева DOM А когда выполняется команда setTimeout записи в стек не будет потому что seTimeout асинхронная команда Цитата:
|
Цитата:
var f=function () { var b=1; return function () { alert(b); }; }(); setTimeout(f, 0); |
Цитата:
у Вас в примере setTimout вызывается в глобальном контексте Функция выполняется в другом контексте, отличном от контекста, в котором задается setTimeout. При этом значение this = window, поэтому о передаче правильного this надо позаботиться отдельно. http://javascript.ru/setTimeout правда контекст к рекурсии никакого отношения не имеет-а имеет значение асинхронность setTimout Этот метод выполняет код(или функцию), указанный в первом аргументе, асинхронно, с задержкой в delay миллисекунд. я так понимаю что даже если указать delay=0 все равно метод будет выполнятся асинхронно |
Цитата:
|
Извините, я неправильно понял мысль. Вы, наверное, имели ввиду, что функция, записанная в setTimeout исполняется в глобальном исполнительном контексте, а я имел ввиду, что эта функция привязывается к лексическому окружению, в котором она определена. Оба эти утверждения верны.
|
Цитата:
|
Цитата:
|
Цитата:
Поэтому оба кода, приведенные выше, являются невалидными, хотя браузер не выдаёт ошибку. |
Цитата:
|
oneguy,
ты какую там спецификацию то смотришь родной? а то прям любишь тыкать на нее, да вот аргументов нет.. Читай внимательно спецификацию, что бы дураком перед другими не казаться: "use strict"; try { var i = 0; function a () { i++; a(); } a(); } catch (e) { alert('ваш ёбаный стек равен каким-то сраным: '+i+' вызовам'); }спецификация запрещает это делать в строгом режиме |
Да, сейчас я аргументирую своё утверждение с помощью спецификации.
Спецификация запрещает объявлять функции внутри блоков в любом режиме, не только строгом. http://es5.javascript.ru/x12.html#x12 - здесь приведен список возможностей для Statement и в нём нет FunctionDeclaration. Там же приводится замечание, касающееся нашей темы. Цитата:
|
Цитата:
Код:
Похоже, исполняемый на этой странице сценарий занят или не отвечает. Вы можете остановить его сейчас или продолжить и посмотреть, сможет ли он завершить свою работу. |
devote, я считаю, что у oneguy правильный подход, куда ещё тыкаться как не в спецификацию, только надо ссылку кидать, где в спецификации эта информация (спецификация-то большая).
|
oneguy,
а может стоит читать официальные документы а не чейто перевод? я понимаю что Илья переводил, и все такое. Но английский это язык который каждый понимает по своему. И читать, а темболее утверждать надо по официальным документам а не по тем что кем-то переведены не официально. |
Цитата:
|
Цитата:
Цитата:
|
Вот оригинал спецификации (на английском языке, в PDF формате)
http://www.ecma-international.org/pu...T/Ecma-262.pdf Смотрите 12 раздел. |
oneguy,
тяжкая документация, но не слово об операторах в скобках. Видимо где то в других разделах описано, а в этом описано лишь это: v=1; var foo = {bar: function () {alert(this.v);}, v:2}; false || foo.bar(); // 2 (у меня 1) // тоесть описана работа без скобок |
Цитата:
|
Часовой пояс GMT +3, время: 14:33. |