Замыкание (программирование)

Поделись знанием:
Перейти к: навигация, поиск

Замыкание (англ. closure) в программировании — функция первого класса, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции в окружающем коде и не являющиеся её параметрами. Говоря другим языком, замыкание — функция, которая ссылается на свободные переменные в своём контексте.

Замыкание, так же как и экземпляр объекта, есть способ представления функциональности и данных, связанных и упакованных вместе.

Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. Синтаксически это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции.

В случае замыкания ссылки на переменные внешней функции действительны внутри вложенной функции до тех пор, пока работает вложенная функция, даже если внешняя функция закончила работу, и переменные вышли из области видимости.[1]

Замыкание связывает код функции с её лексическим окружением (местом, в котором она определена в коде). Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён. От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам.

Пример работы замыканий на Scheme:

(define (make-adder n)       ; возвращает замкнутое лямбда-выражение
  (lambda (x)                ; в котором x - связанная переменная,
    (+ x n)))                ; а n - свободная (захваченная из внешнего контекста)

(define add1 (make-adder 1)) ; делаем процедуру для прибавления 1
(add1 10)                    ; возвращает 11

(define sub1 (make-adder -1)); делаем процедуру для вычитания 1
(sub1 10)                    ; возвращает 9
Пример работы на JavaScript:
var myClosure = (function outerFunction() {
 
  var hidden = 1;
 
  return {
    inc: function innerFunction() {
      return hidden++;
    }
  };
 
}());
 
myClosure.inc();  // возвращает 1
myClosure.inc();  // возвращает 2
myClosure.inc();  // возвращает 3

Когда JS-код работает — локальные переменные хранятся в scope. В JavaScript локальные переменные могут оставаться в памяти даже после того, как функция вернула значение.

Замыкание создается в JavaScript Все функции в JavaScript это замыкания, когда задается функция — задается замыкание. Так что замыкание создается при определении функции. Но нужно понимать разницу между созданием замыкания и созданием нового scope-объекта: замыкание (функция + ссылка на текущую цепочку scope-объектов) создается при определении функции, но новый scope-объект создается (и используется для модификации цепочки scope-объектов замыкания) при вызове функции.

Замыкание уничтожается как и любой другой объект в JavaScript. Сборщик мусора обрабатывает замыкание, когда на него больше нет ссылок. (т.е. сносит).



См. также

Напишите отзыв о статье "Замыкание (программирование)"

Примечания

  1. [www.ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html#UG Blocks Can Be Closures — Containers, Blocks, and Iterators — Programming Ruby. The Pragmatic Programmer’s Guide.]


Отрывок, характеризующий Замыкание (программирование)

Они шагом подъехали к амбару, у которого стояла большая толпа мужиков.
Некоторые мужики сняли шапки, некоторые, не снимая шапок, смотрели на подъехавших. Два старые длинные мужика, с сморщенными лицами и редкими бородами, вышли из кабака и с улыбками, качаясь и распевая какую то нескладную песню, подошли к офицерам.
– Молодцы! – сказал, смеясь, Ростов. – Что, сено есть?
– И одинакие какие… – сказал Ильин.
– Развесе…oo…ооо…лая бесе… бесе… – распевали мужики с счастливыми улыбками.
Один мужик вышел из толпы и подошел к Ростову.
– Вы из каких будете? – спросил он.
– Французы, – отвечал, смеючись, Ильин. – Вот и Наполеон сам, – сказал он, указывая на Лаврушку.
– Стало быть, русские будете? – переспросил мужик.
– А много вашей силы тут? – спросил другой небольшой мужик, подходя к ним.
– Много, много, – отвечал Ростов. – Да вы что ж собрались тут? – прибавил он. – Праздник, что ль?
– Старички собрались, по мирскому делу, – отвечал мужик, отходя от него.
В это время по дороге от барского дома показались две женщины и человек в белой шляпе, шедшие к офицерам.
– В розовом моя, чур не отбивать! – сказал Ильин, заметив решительно подвигавшуюся к нему Дуняшу.
– Наша будет! – подмигнув, сказал Ильину Лаврушка.
– Что, моя красавица, нужно? – сказал Ильин, улыбаясь.
– Княжна приказали узнать, какого вы полка и ваши фамилии?
– Это граф Ростов, эскадронный командир, а я ваш покорный слуга.
– Бе…се…е…ду…шка! – распевал пьяный мужик, счастливо улыбаясь и глядя на Ильина, разговаривающего с девушкой. Вслед за Дуняшей подошел к Ростову Алпатыч, еще издали сняв свою шляпу.
– Осмелюсь обеспокоить, ваше благородие, – сказал он с почтительностью, но с относительным пренебрежением к юности этого офицера и заложив руку за пазуху. – Моя госпожа, дочь скончавшегося сего пятнадцатого числа генерал аншефа князя Николая Андреевича Болконского, находясь в затруднении по случаю невежества этих лиц, – он указал на мужиков, – просит вас пожаловать… не угодно ли будет, – с грустной улыбкой сказал Алпатыч, – отъехать несколько, а то не так удобно при… – Алпатыч указал на двух мужиков, которые сзади так и носились около него, как слепни около лошади.
– А!.. Алпатыч… А? Яков Алпатыч!.. Важно! прости ради Христа. Важно! А?.. – говорили мужики, радостно улыбаясь ему. Ростов посмотрел на пьяных стариков и улыбнулся.
– Или, может, это утешает ваше сиятельство? – сказал Яков Алпатыч с степенным видом, не заложенной за пазуху рукой указывая на стариков.
– Нет, тут утешенья мало, – сказал Ростов и отъехал. – В чем дело? – спросил он.
– Осмелюсь доложить вашему сиятельству, что грубый народ здешний не желает выпустить госпожу из имения и угрожает отпречь лошадей, так что с утра все уложено и ее сиятельство не могут выехать.
– Не может быть! – вскрикнул Ростов.
– Имею честь докладывать вам сущую правду, – повторил Алпатыч.
Ростов слез с лошади и, передав ее вестовому, пошел с Алпатычем к дому, расспрашивая его о подробностях дела. Действительно, вчерашнее предложение княжны мужикам хлеба, ее объяснение с Дроном и с сходкою так испортили дело, что Дрон окончательно сдал ключи, присоединился к мужикам и не являлся по требованию Алпатыча и что поутру, когда княжна велела закладывать, чтобы ехать, мужики вышли большой толпой к амбару и выслали сказать, что они не выпустят княжны из деревни, что есть приказ, чтобы не вывозиться, и они выпрягут лошадей. Алпатыч выходил к ним, усовещивая их, но ему отвечали (больше всех говорил Карп; Дрон не показывался из толпы), что княжну нельзя выпустить, что на то приказ есть; а что пускай княжна остается, и они по старому будут служить ей и во всем повиноваться.