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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// внешняя функция
function hello(name) {
	// внутренняя функция-замыкание
	// возвращаем её как результат работы внешней
	return function() {
		// внутренняя функция выводит сообщение на экран
		console.log("Привет, " + name);
	}
}

// создаём новые переменные, используя замыкание
mike = hello("Миша");
maxim = hello("Максим")
// запускаем внутреннюю функцию с нашими параметрами, просто указав имена переменной
mike();
maxim();
Что такое замыкание в программировании

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

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

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

// внешняя функция, у которой есть свой параметры
function greeting(hi) {
	// внутренняя функция-замыкание, тоже со своим параметром
	// возвращаем её как результат работы внешней
	return function(name) {
		// внутренняя функция выводит сообщение на экран
		console.log(hi + ", " + name);
	}
}

// создаём новые переменные, используя замыкание
morning = greeting("Доброе утро");
thnx = greeting("Спасибо за комментарий")
// запускаем внутреннюю функцию с нашими параметрами, указав параметры вызова
morning("коллеги");
thnx("Павел");
Что такое замыкание в программировании

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

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

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

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

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

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

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

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

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

Что дальше

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

Текст:

Михаил Полянин

Редактор:

Максим Ильяхов

Художник:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Соцсети:

Алина Грызлова

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Владимир Олохтонов о работе старшего разработчика в Авито
Владимир Олохтонов о работе старшего разработчика в Авито

Путь от монтажника локальных сетей до инженера машинного обучения.

easy
Как запустить операционку внутри операционки внутри операционки
Что такое виртуализация

Как запустить операционку внутри операционки внутри операционки

hard
Как учатся нейронки

Самое простое объяснение на картинках.

hard
Зачем нужны переменные в CSS
Зачем нужны переменные в CSS

Чтобы работать со стилями ещё гибче и проще.

medium
С какого языка начать изучение программирования

У нас нет однозначного ответа, но есть кое-что получше.

easy
Какая бывает память
Какая бывает память

Краткий обзор для тех, кто не хочет глубоко копать.

medium
10 главных конструкций языка C
10 главных конструкций языка C

Простое введение в сложный язык.

easy
Системный администратор — что нужно знать, чтобы получать 160 000 рублей
Системный администратор — что нужно знать, чтобы получать 160 000 рублей

Это не тот администратор, который ставит вам Windows.

easy
С чего начать в IT

Даже если вы абсолютный гуманитарий — выход есть.

easy
ColdFusion — редкий и важный язык программирования
ColdFusion — редкий и важный язык программирования

Один из первых серверных языков, который смог найти себе место в современном мире.

easy
medium