> Что происходит при запуске бесконечной рекурсивной функции с console.log в браузере (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Точка

Стек: JavaScript

> Пример ответа

Короткий ответ

Бесконечная рекурсивная функция с console.log в браузере приведёт к ошибке переполнения стека (stack overflow). Каждый рекурсивный вызов добавляет новый фрейм в стек вызовов, а console.log синхронно взаимодействует с DevTools, дополнительно нагружая стек. Браузер ограничивает глубину стека (обычно ~10-15 тысяч вызовов), после чего выбрасывает исключение RangeError: Maximum call stack size exceeded.

Подробное объяснение

JavaScript использует стек вызовов (call stack) для управления выполнением функций. Каждый вызов функции создаёт фрейм с локальными переменными, параметрами и адресом возврата. При бесконечной рекурсии стек растёт до предела, установленного движком (V8 - около 10-15 тысяч фреймов). console.log добавляет накладные расходы: он вызывает внутренние методы форматирования и отправки сообщения в DevTools, что может ускорить исчерпание стека из-за дополнительных аллокаций.

В браузере событийный цикл (event loop) не вмешивается - рекурсия выполняется синхронно в одном тике. Исключение прерывает выполнение, но не крашит вкладку полностью, если не затронуты другие части приложения. Однако до выброса ошибки интерфейс зависает, так как основной поток заблокирован.

На практике

  • Избегайте рекурсии без базового случая или с неверным условием выхода.
  • Для глубоких рекурсий используйте хвостовую рекурсию (если движок поддерживает TCO) или переписывайте на итерацию (цикл, стек вручную).
  • console.log в рекурсии - плохая практика для продакшена: он не только замедляет выполнение, но и может привести к утечкам памяти в DevTools (сохранение ссылок на объекты).
  • В Node.js поведение аналогично, но лимит стека можно увеличить через --stack-size, хотя это не решает проблему логически.

Пример кода

JAVASCRIPT
function recurse() {
console.log('still going');
recurse();
}
try {
recurse();
} catch (e) {
console.error(e.message); // "Maximum call stack size exceeded"
}

Как отвечать на собеседовании

Начните с прямого ответа: "произойдёт stack overflow". Объясните механизм стека вызовов и роль console.log как синхронной операции. Упомяните, что браузер не крашится, а выбрасывает исключение. Для уровня senior добавьте про event loop (рекурсия блокирует основной поток), про разницу между синхронной и асинхронной рекурсией (setTimeout не даст stack overflow, но создаст другую проблему - бесконечные макротаски). Покажите понимание ограничений движка и практических последствий (зависание UI).

Что проверяет интервьюер

  • Понимание стека вызовов и его ограничений.
  • Знание синхронной природы рекурсии в JavaScript.
  • Осведомлённость о влиянии console.log на производительность.
  • Умение различать синхронные и асинхронные паттерны.
  • Способность предложить альтернативы (итерация, хвостовая рекурсия).

Типичные ошибки

  • Утверждение, что console.log асинхронен - он синхронен, хотя вывод в DevTools может быть отложен.
  • Мысль, что браузер "зависнет навсегда" - на самом деле будет выброшено исключение.
  • Игнорирование роли event loop - рекурсия выполняется до исчерпания стека, event loop не прерывает её.
  • Предложение использовать setTimeout(recurse, 0) как решение - это не рекурсия, а бесконечная очередь макрозадач, которая тоже проблема, но иная.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью