На самом деле, вы не создаете там рекурсивную функцию.Вызывая setTimeout
, он больше не называет себя.Единственное замыкание, созданное здесь, - это анонимная функция для setTimeout
, после выполнения которой сборщик мусора распознает, что ссылка на предыдущий экземпляр может быть очищена.Это, вероятно, не произойдет мгновенно, но вы определенно не можете создать stack overflow
, используя это.Давайте рассмотрим этот пример:
function myFunc() {
var bigarray = new Array(10000).join('foobar');
setTimeout(myFunc, 200);
}
myFunc();
Наблюдение за использованием памяти в вашем браузере.Он будет постоянно расти, но через некоторое время (20-40 секунд для меня) он снова будет полностью очищен.С другой стороны, если мы создадим реальную рекурсию, подобную этой:
function myFunc() {
var bigarray = new Array(10000).join('foobar');
myFunc();
}
myFunc();
Наше использование памяти будет расти, браузеры заблокируются, и мы наконец создадим эту stack overflow
.Javascript не реализует рекурсию хвоста , поэтому мы получим переполнение во всех случаях.
обновление
похоже, я ошибался в своем первом примере.Такое поведение верно только в том случае, если не вызывается контекст-функция (например, с использованием анонимной функции).Если мы переписываем это как
function myFunc() {
var bigarray = new Array(10000).join('foobar');
setTimeout(function() {
myFunc();
}, 200);
}
myFunc();
Память браузера больше не освобождается.Растет вечно.Это может быть из-за того, что любая внутренняя закрытость сохраняет ссылку на bigarray
.Но все равно.