Найти тему
Журнал «Код»

Что такое замыкание в программировании

Оглавление

Это когда вкладываешь одну функцию в другую

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

Для начала потребуется два термина: область видимости и стек. Если нужно вспомнить:

Что такое область видимости

Область видимости определяет, к каким переменным функция, команда или другая переменная может получить доступ, а к каким нет. Проще говоря, что каждая функция «видит» — видит ли она те переменные и объекты, которые созданы за её пределами? Видит ли она то, что вложено в функции, которые запускаются внутри неё?

Обычно так: если переменная объявлена в самой программе, к ней можно получить доступ из вложенной функции. А если объявить переменную внутри функции, то не обратиться к ней извне не получится.

Что такое стек

Стек — это как список задач при выполнении программы. Сначала компьютер исполняет один код, внутри которого появляется какая-то функция — это как будто отдельная программа. Компьютер откладывает текущую программу, делает себе в стеке пометку «вернуться сюда, когда доделаю новую программу» и исполняет эту новую функцию. Исполнил — смотрит в стек, куда вернуться. Возвращается туда.

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

Что такое замыкание

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

Чаще всего это используют, чтобы сделать переменную, которая на самом деле работает как функция.

Звучит сложно, объясним на примерах.

-2

Пример замыкания в коде

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

Обратите внимание на две переменные в конце: mike и maxim. По сути, эти переменные — ссылки на вызов результата функции hello (), но с конкретным параметром.

-3

Ещё один пример, посложнее

Только что мы сделали просто — привязали сообщение к переменной без возможности на него повлиять. Но можно создавать такие переменные, у которых могут быть свои параметры — и в них уже передавать любые значения.

Для примера сделаем замыкание и заведём две переменные — каждая будет выдавать сообщение со своим началом фразы, а продолжение будем передавать им в виде параметра:

-4

Причём здесь область видимости

Из последнего примера видно, что объявление переменных происходит так:

  • переменной присваивается результат выполнения внешней функции;
  • этот результат зависит от параметра, который мы ей передали;
  • потом, при обращении к переменной, происходит обработка только второго параметра, а первый хранится где-то в памяти и подставляется в нужный момент.

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

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

-5

Зачем нужны замыкания

На замыканиях строится около половины алгоритмов в функциональном программировании. А ещё на них можно построить много разного:

  • изолировать логику выполнения фрагментов кода, если это не позволяют сделать встроенные возможности языка (как в JavaScript);
  • лучше структурировать код, особенно при организации функций, которые отличаются только несколькими элементами;
  • реализовать инкапсуляцию в тех языках, где её нет.

Что дальше

Следующий шаг — попробовать замыкания в деле. Напишем небольшой код и проверим, как работают замыкания и для чего они могут пригодиться.

Наука
7 млн интересуются