Замикання (програмування)
У програмуванні замиканням (англ. closure) називають підпрограму, що виконується в середовищі, яке містить одну або більше зв'язаних змінних. Підпрограма має доступ до цих змінних під час виконання.
Застосування замикань асоціюється з функціональним програмуванням. У функціональному програмуванні за допомогою замикань можуть моделюватись такі конструкції, як об'єкти в інших мовах програмування.
У деяких мовах програмування[яких?] замикання створюється для підпрограм, що визначені всередині інших підпрограм, і внутрішня підпрограма має доступ до локальних змінних зовнішньої. Під час виконання, коли обчислюється зовнішня підпрограма, утворюється замикання, до якого потрапляє код внутрішньої підпрограми, та посилання на ті змінні зовнішньої підпрограми, що використовуються у внутрішній підпрограмі. Посилання на змінні зовнішньої підпрограми залишаються дійсними всередині вкладеної внутрішньої підпрограми доти, поки існує ця вкладена підпрограма, навіть якщо зовнішня підпрограма завершила виконання і вийшла з області видимості. Концепцію замикань було повністю розроблено в 1960-ті роки та реалізовано як особливість мови програмування Scheme. Відтоді було розроблено багато мов програмування з підтримкою замикань.
Приклад реалізації на Lua
function addfunc(x)
return function(y) -- Повертає нову функцію без назви, яка додає x до аргументу
return x + y -- Коли ми будемо посилатися на змінну x, що знаходиться поза даною областю й існування якої менше ніж даної безіменної функції,
-- Lua створить замикання
end
end
num_plus = addfunc(2) -- Тепер num_plus - функція, в якій замість x підставлено 2
print(num_plus(5)) -- В результаті буде виведено 7
Приклад на JavaScript
Функції (зокрема в JS) можна зобразити як спеціальні об'єкти, що включають код, який можна запускати, а також властивості. Кожна функція має властивість [scope]
, котра відображає оточення на момент створення функції. Якщо ж функцію створено викликом з іншої функції, тоді це відображення старого оточення «перекривається» нової функцією і це називається замиканням.
const myClosure = (function outerFunction() {
let hidden = 1;
return {
innerFunction() {
return hidden++;
}
};
}());
myClosure.innerFunction(); // повертає 1
myClosure.innerFunction(); // повертає 2
myClosure.innerFunction(); // повертає 3
Коли JS-код працює, локальні змінні зберігаються в scope. В JavaScript локальні змінні можуть лишатись в пам'яті навіть після того, як функція повернула значення.
Створення замикання в JavaScript
Усі функції в JavaScript — це замикання; коли задається функція — задається замикання. Так що замикання створюється при визначенні функції. Але треба розуміти різницю між створенням замикання і створенням нового scope-об'єкту: замикання[1] (функція + посилання на поточний ланцюжок scope-об'єктів) створюється при визначенні функції, але новий scope-об'єкт створюється (і використовується для модифікації ланцюжка scope-об'єктів замикання) при виклику функції.
Видалення замикання
Збірник сміття обробляє і видаляє замикання, як і будь-який інший об'єкт у JavaScript, коли на нього більше немає посилань.
Примітки
- Learning Javascript with Object Graphs - How To Node - NodeJS. howtonode.org. Процитовано 24 квітня 2016.