|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
12.12.2020, 07:18 | #11 |
Новичок
Джуниор
Регистрация: 07.01.2019
Сообщений: 2
|
Запоздалый, но пристальный взгляд на замыкания.
Вот еще небольшое рассуждение по поводу замыканий:
1. Допустим, мы вызываем какую-то функцию, возвращающую некоторое число, например, объявленную в глобальной области. Назовем это статическим объявлением функции. Это оправдано тем, что функция всегда присутствует в памяти, выделенной ей интерпретатором, и к ней всегда можно обратиться из любого места кода. Для выполнения этой функции в стек добавляется новая временная область памяти. После того, как функция выполнена в этой области памяти и возвращаемое значение передано вызывающему коду, эта область памяти высвобождается, все данные, которые в ней находились, удаляются. Но функция (как и любой другой объект из глобальной области), все равно присутствует в глобальной области памяти. Даже если в теле этой функции есть ссылки на какие-то переменные из глобальной области, все равно этот механизм вызова функции полностью сохраняется. Т.е. как только происходит выход из этой функции, временно выделенная для нее область памяти высвобождается. 2. Теперь, допустим, мы вызываем внутри нашего кода какую-то функцию (назовем ее первичной функцией), т.е. какой-то код (назовем его вспомогательным), находящийся в теле этой функции. И этот вспомогательный код объявляет другую функцию (назовем ее вторичной функцией) и возвращает эту вторичную функцию в качестве возвращаемого значения. Здесь ключевой момент– не в коде создается, а код создает. Т.е. если бы мы не вызвали код первичной функции, то вторичная функция бы не была создана. Ее и в памяти-то нигде не было бы. К ней нельзя было бы обратиться. Интерпретатор не размещает ее в памяти, пока не будет вызвана первичная функция. В этом вспомогательном коде могут быть объявлены и инициализированы переменные, а внутри тела этой вторичной функции могут быть обращения к этим переменным, т.е. код может захватить некоторые ресурсы и ссылки на часть этих ресурсов передать в функцию. Тогда эта возвращенная вторичная функция будет иметь такую особенность, что внутри нее будут ссылки на некие ресурсы, находящиеся где-то. И если бы эти ресурсы были удалены, то при запуске этой функции на выполнение произошла бы ошибка (были бы не найдены какие-то затребованные данные). Поэтому когда такая функция объявляется в выполняемом коде (т.е. код ее создает динамически) и при возвращении из кода присваивается какой-то переменной, то чтобы эта операция имела смысл, интерпретатор сохраняет в памяти созданные в коде данные, на которые ссылается эта функция. Именно память под данные, на которые ссылается вторичная функция, выделенная в момент выполнения кода первичной функции (в этот момент как раз создается и размещается в памяти и вторична функция) сохраняется. Остальная память, временно выделявшаяся при работе кода первичной функции, высвобождается, как только первичная функция заканчивает работу. Т.е. эту вторичную функцию можно рассматривать просто как обычный объект, содержащий в своих полях некоторые данные. Естественно, пока на этот объект где-то будут оставаться ссылки, будут сохраняться в памяти и данные этого объекта. Пока где-то в коде существует действующая ссылка на эту вторичную функцию, будут работоспособными и все ссылки внутри этой функции на участки памяти с данными, которые выделялись при создании этой вторичной функции. Если мы второй раз вызовем первичную функцию, мы создадим уже совершенно другой объект вторичной функции, со своими данными. Эта вторичная функция, т.е. этот динамически созданный объект, называется, вы не поверите, - замыканием. |
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
адаптер замыкания на себя | kral123 | Свободное общение | 2 | 15.02.2013 16:46 |
Замыкания и setTimeout | Виталий Желтяков | JavaScript, Ajax | 7 | 26.01.2012 13:16 |
abc was not declared in this scope | Farrel | Qt и кроссплатформенное программирование С/С++ | 2 | 21.04.2011 17:56 |
error: was not declared in this scope | Serjuk | Помощь студентам | 2 | 29.03.2011 15:59 |
Замыкания | Viconte | JavaScript, Ajax | 1 | 07.11.2010 21:08 |