Замыкание

Оригинальное название: closure

Коротко

Функция, которая запоминает переменные из того места, где была создана, и продолжает пользоваться ими даже после того, как внешний код завершился.

Что такое «Замыкание»

Обычно локальные переменные исчезают, когда функция заканчивает работу. Но если внутри неё создана другая функция и та использует эти переменные, язык сохраняет их, пока жива внутренняя функция. Связку «функция плюс захваченное окружение» и называют замыканием. Понятие тесно связано с областью видимости: замыкание видит то, что было доступно в месте его объявления, а не в месте вызова.

Пример на JavaScript

function makeCounter() {
  let count = 0;
  return () => ++count;
}

const next = makeCounter();
next(); // 1
next(); // 2 — count сохранился между вызовами

Переменная count недоступна снаружи: изменить её можно только через возвращённую функцию. Так в JavaScript делали приватное состояние задолго до появления приватных полей классов. На замыканиях построены обработчики событий, отложенные вызовы через setTimeout, функции-фабрики и мемоизация.

Замыкания в PHP

В PHP анонимная функция не видит внешние переменные автоматически — их перечисляют в use. По умолчанию значение копируется в момент создания функции, а с & захватывается ссылка. Стрелочные функции fn, появившиеся в PHP 7.4, захватывают внешние переменные сами, по значению.

$discount = 0.9;
$apply  = function (float $price) use ($discount) { return $price * $discount; };
$apply2 = fn(float $price) => $price * $discount;

В WordPress так передают дополнительные данные в обработчики хуков: add_filter('the_title', fn($title) => $prefix . $title).

Ловушка с var в цикле

Классическая ошибка JavaScript — создать функции в цикле с переменной var. Все они замкнут одну и ту же переменную и после цикла увидят её последнее значение: три обработчика выведут «3, 3, 3». С let на каждой итерации создаётся новая переменная, и проблема исчезает. Вторая частая беда — утечки памяти: замыкание удерживает всё, на что ссылается, например большой массив или DOM-элемент, хотя они давно не нужны.

Обновлено:

Все термины раздела «Backend»

Что будем искать? Например,Продвижение