Страницы

Поиск по вопросам

среда, 13 февраля 2019 г.

Каким образом в функции может сохраняться значение переменной?

Изучаю JS на http://learn.javascript/, сейчас читаю подраздел «Замыкание функции изнутри» раздела «Замыкания, область видимости». В пункте «Возврат функции» описывается пример с вложенной функцией.
Я, собственно, не понимаю, как counter при каждом запуске вспоминает переменную currentCount, учитывая написанное в том же разделе, что LexicalEnviroment при каждом завершении функции стирается из памяти, а при каждом новом запуске создается заново.
Не пойму, где хранится currentCount, если лексическое окружение стирается каждый раз?


Ответ

Такие вопросы вызывают у меня скупую слезу на бороду.
Всё просто - LexicalEnvironment действительно уничтожается после окончания работы вызова. Но в примере работа не закончена, т. к. возвращаемая функция сохранила ссылку на родительский [makeCounter] объект переменных.
То есть пока возвращенная функция будет жива, родительский LE обязан сохранится, вдруг при выполнении нужно обратится к родительской функции за переменными (что и происходит: в возвращённой функции нет переменной currentCount)?
Сборщики мусора работают по алгоритму ссылок (Mark and sweep), в общих чертах это как-то так:
Находятся корни, т. е. то, что всегда будет существовать (в браузерах это объект window, его же нельзя удалить). После каждого пробуждения, он [сборщик] рекурсивно обходит корни и помечает всё, до чего может дотянутся; это считается как нужное и полезное. Всё остальное считается недостижимым и память из-под них возвращается среде.
А теперь вспомним, что возвращённая функция, условно сохранённая в window, ссылается на родительский LexicalEnvironment через скрытое свойство [[Scope]] Сборщик просто не может удалить его - window -> counter -> [[Scope]]
Это объясняет почему новый вызов makeCounter создал девственно чистый счётчик - каждый вызов функции выдаёт ей кристально новый LexicalEnvironment

Замыкания - вообще очень интересная вещь, которая может быть очень мощной, а может в конец запутать, если не знать принципов работы замыканий.

Комментариев нет:

Отправить комментарий