Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 21.07.2012, 18:09
Кандидат Javascript-наук
Отправить личное сообщение для hrundel Посмотреть профиль Найти все сообщения от hrundel
 
Регистрация: 01.08.2009
Сообщений: 102

Косвенная рекурсия в 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() вызывается много раз подряд. Почему так происходит?
Ответить с цитированием
  #2 (permalink)  
Старый 21.07.2012, 18:28
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

hrundel, http://css-live.ru/javascript/javasc...rekursiya.html - не самая хорошая статья.

Что проиходит в первом коде, приведенном Вами? Подсказка:
Сообщение от hrundel
Хром: Uncaught RangeError: Maximum call stack size exceeded

Лично я бы не стал разбирать рекурсию на таких отвлеченных примерах. Для начала попробуйте зарыться в DOM.
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 21.07.2012 в 18:30.
Ответить с цитированием
  #3 (permalink)  
Старый 21.07.2012, 18:43
Аватар для vadim5june
Студент
Отправить личное сообщение для vadim5june Посмотреть профиль Найти все сообщения от vadim5june
 
Регистрация: 30.04.2012
Сообщений: 1,113

Сообщение от hrundel Посмотреть сообщение
браузеры не выдают ошибку, хотя происходит та же ситуация: функция recursMe() вызывается много раз подряд. Почему так происходит?
стек не переполняется-потому что SEtTimeout выполняется в глобальном контексте
там же ошибка переполнения стека
Stack overflow at line:135
с setTimiout у Вас нерекурсивное обращение к функции

Последний раз редактировалось vadim5june, 21.07.2012 в 18:52.
Ответить с цитированием
  #4 (permalink)  
Старый 22.07.2012, 17:59
Кандидат Javascript-наук
Отправить личное сообщение для hrundel Посмотреть профиль Найти все сообщения от hrundel
 
Регистрация: 01.08.2009
Сообщений: 102

Сообщение от vadim5june
стек не переполняется-потому что SEtTimeout выполняется в глобальном контексте
там же ошибка переполнения стека
Stack overflow at line:135
с setTimiout у Вас нерекурсивное обращение к функции
А как обычному человеку определять, когда рекурсивно обращение к функции, а когда нерекурсивное? Я считаю, что косвенная рекурсия всегда вызвана одним и тем же - функция вызывает саму себя через цепочку других функций. Здесь такая ситуация и во втором примере и в третьем, но результат разный.
Что за глобальный контекст у setTimeout()? Как он может влиять на переполнение стека?
Ответить с цитированием
  #5 (permalink)  
Старый 22.07.2012, 18:06
Аватар для B@rmaley.e><e
⊞ Развернуть
Отправить личное сообщение для B@rmaley.e><e Посмотреть профиль Найти все сообщения от B@rmaley.e><e
 
Регистрация: 11.01.2010
Сообщений: 1,810

Сообщение от hrundel
Здесь такая ситуация и во втором примере и в третьем
Наглая ложь. Рекурсия имеет место, когда внутри функции нужно получить результат её вызова от других (впрочем, не обязательно отличных от текущих) аргументов. В случае с setTimeout никаких результатов никто дожидаться не будет. JS где-то у себя внутри сделает пометку "через сколько-то мс запустить такую-то функцию" и спокойно продолжит исполнение.
Ответить с цитированием
  #6 (permalink)  
Старый 22.07.2012, 19:13
Аватар для vadim5june
Студент
Отправить личное сообщение для vadim5june Посмотреть профиль Найти все сообщения от vadim5june
 
Регистрация: 30.04.2012
Сообщений: 1,113

Сообщение от hrundel Посмотреть сообщение
Я считаю, что косвенная рекурсия всегда вызвана одним и тем же - функция вызывает саму себя через цепочку других функций. Здесь такая ситуация и во втором примере и в третьем, но результат разный.
Что за глобальный контекст у setTimeout()? Как он может влиять на переполнение стека?
когда вызывается setTimeout эта цепочка прерывается
В чем смысл рекурсии-когда функция вызывает саму себя то текущее состояние записывается в стек -потому что потом должны быть выполнены команды которые стоят после операции вызова
Это обычно например обход дерева DOM
А когда выполняется команда setTimeout записи в стек не будет потому что seTimeout асинхронная команда
Сообщение от hrundel Посмотреть сообщение
Что за глобальный контекст у setTimeout()? Как он может влиять на переполнение стека?
Вы не знаете разве что функции записанные в setTimeout выполняются в глобальном контексте window а не в контексте объекта вызывающей функции

Последний раз редактировалось vadim5june, 22.07.2012 в 19:33.
Ответить с цитированием
  #7 (permalink)  
Старый 24.07.2012, 05:27
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 31.05.2012
Сообщений: 396

Сообщение от vadim5june
Вы не знаете разве что функции записанные в setTimeout выполняются в глобальном контексте window а не в контексте объекта вызывающей функции
А вот и неправда Функции, записанные в setTimeout выполняются в том контексте, в которым они определены. Пример:
var f=function () {
  var b=1;
  return function () {
    alert(b);
  };
}();
setTimeout(f, 0);
Ответить с цитированием
  #8 (permalink)  
Старый 24.07.2012, 07:56
Аватар для vadim5june
Студент
Отправить личное сообщение для vadim5june Посмотреть профиль Найти все сообщения от vadim5june
 
Регистрация: 30.04.2012
Сообщений: 1,113

Сообщение от oneguy Посмотреть сообщение
А вот и неправда Функции, записанные в setTimeout выполняются в том контексте, в которым они определены.
[/JS]
я то имел ввиду вызывающую функцию-это функция где сам setTimout вызывается
у Вас в примере setTimout вызывается в глобальном контексте

Функция выполняется в другом контексте, отличном от контекста, в котором задается setTimeout.
При этом значение this = window, поэтому о передаче правильного this надо позаботиться отдельно.

http://javascript.ru/setTimeout
правда контекст к рекурсии никакого отношения не имеет-а имеет значение асинхронность setTimout
Этот метод выполняет код(или функцию), указанный в первом аргументе, асинхронно, с задержкой в delay миллисекунд.
я так понимаю что даже если указать delay=0 все равно метод будет выполнятся асинхронно

Последний раз редактировалось vadim5june, 24.07.2012 в 08:13.
Ответить с цитированием
  #9 (permalink)  
Старый 24.07.2012, 16:58
Кандидат Javascript-наук
Отправить личное сообщение для hrundel Посмотреть профиль Найти все сообщения от hrundel
 
Регистрация: 01.08.2009
Сообщений: 102

Сообщение от oneguy Посмотреть сообщение
А вот и неправда Функции, записанные в setTimeout выполняются в том контексте, в которым они определены. Пример:
var f=function () {
  var b=1;
  return function () {
    alert(b);
  };
}();
setTimeout(f, 0);
Странный пример Непонятно, как он что-то может доказать? По-моему, очевидный результат, равный '1'. Что-то ваша мысль до конца не раскрыта.
Ответить с цитированием
  #10 (permalink)  
Старый 24.07.2012, 23:16
Профессор
Отправить личное сообщение для oneguy Посмотреть профиль Найти все сообщения от oneguy
 
Регистрация: 31.05.2012
Сообщений: 396

Извините, я неправильно понял мысль. Вы, наверное, имели ввиду, что функция, записанная в setTimeout исполняется в глобальном исполнительном контексте, а я имел ввиду, что эта функция привязывается к лексическому окружению, в котором она определена. Оба эти утверждения верны.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Книга] Stoyan Stefanov, Javascript Patterns Dmitry A. Soshnikov Учебные материалы 20 13.08.2013 11:37
Книга: JavaScript. Сильные стороны Magneto Учебные материалы 16 21.04.2013 15:28
Первый Moscow JavaScript Meetup korenyushkin Общие вопросы Javascript 0 26.07.2011 15:23
Последние книги по JavaScript! monolithed Учебные материалы 7 26.10.2010 19:40
Выдвет ошибку JavaScript Ромио Opera, Safari и др. 4 21.10.2010 20:34