#javascript #javascript_faq
Изучаю JS на http://learn.javascript/, сейчас читаю подраздел «Замыкание функции изнутри» раздела «Замыкания, область видимости». В пункте «Возврат функции» описывается пример с вложенной функцией. Я, собственно, не понимаю, как counter при каждом запуске вспоминает переменную currentCount, учитывая написанное в том же разделе, что LexicalEnviroment при каждом завершении функции стирается из памяти, а при каждом новом запуске создается заново. Не пойму, где хранится currentCount, если лексическое окружение стирается каждый раз?
Ответы
Ответ 1
Такие вопросы вызывают у меня скупую слезу на бороду. Всё просто - LexicalEnvironment действительно уничтожается после окончания работы вызова. Но в примере работа не закончена, т. к. возвращаемая функция сохранила ссылку на родительский [makeCounter] объект переменных. То есть пока возвращенная функция будет жива, родительский LE обязан сохранится, вдруг при выполнении нужно обратится к родительской функции за переменными (что и происходит: в возвращённой функции нет переменной currentCount)? Сборщики мусора работают по алгоритму ссылок (Mark and sweep), в общих чертах это как-то так: Находятся корни, т. е. то, что всегда будет существовать (в браузерах это объект window, его же нельзя удалить). После каждого пробуждения, он [сборщик] рекурсивно обходит корни и помечает всё, до чего может дотянутся; это считается как нужное и полезное. Всё остальное считается недостижимым и память из-под них возвращается среде. А теперь вспомним, что возвращённая функция, условно сохранённая в window, ссылается на родительский LexicalEnvironment через скрытое свойство [[Scope]]. Сборщик просто не может удалить его - window -> counter -> [[Scope]]. Это объясняет почему новый вызов makeCounter создал девственно чистый счётчик - каждый вызов функции выдаёт ей кристально новый LexicalEnvironment. Замыкания - вообще очень интересная вещь, которая может быть очень мощной, а может в конец запутать, если не знать принципов работы замыканий.
Комментариев нет:
Отправить комментарий