Простым языком о замыканиях?

Объясните пожалуйста простым языком, без примеров:
1. Для чего замыкание существуют?
2. В каких условиях они создаются?
  • Вопрос задан
  • 4848 просмотров
Пригласить эксперта
Ответы на вопрос 13
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
1. Для чего замыкание существуют?
Для инкапсуляции данных.
В ООП есть модификаторы доступа (private, protected), которые закрывают доступ к данным извне класса, но позволяют обращаться к ним из методов.
В ФП для этой задачи используют замыкания, закрывая данные внутри функции. Из вне данные недоступны, но вложенные функции имеют к ним доступ.

2. В каких условиях они создаются?
Когда вложенная функция обращается к переменным внешней функции.

Хоть и просили без примеров, но на примере показать проще:
// makeCounter - внешняя функция
function makeCounter(initialValue) {
  var value = +initialValue || 0;
  // counter - внутренняя функция
  // она использует переменную value из внешней функции
  // что-бы это было возможным, для counter создается замыкание,
  // в котором хранится переменная value
  // переменная initialValue функции counter не нужна, поэтому ее можно "забыть"
  return function counter() {
    return value++;
  };
}

// у нас 3 экземпляра функции counter
var counter1 = makeCounter();
var counter2 = makeCounter();
var counter3 = makeCounter(100);
// и для каждой есть своя переменная value
console.log(counter1()); // 0
console.log(counter1()); // 1
console.log(counter2()); // 0
console.log(counter1()); // 2
console.log(counter3()); // 100

// а вот получить как-то напрямую переменную value мы не можем
// инкапсуляция нам не дает поломать данные
Ответ написан
Комментировать
1. У вас есть алгоритм (функция) F, зависящий от некоторого числа переменных (значений), включая N параметров функции и некоторого количества "свободных" переменных (т.е. определённых вне тела функции, но доступных в теле функции на момент его выполнения).
2. У вас есть другая функция G, требующая для своей работы некоторую функцию, зависящую от M параметров (причём N > M).
3. У вас есть желание использовать функцию F как параметр функции G, однако для этого необходимо заранее задать значения всех аргументов, которые G не будет передавать в F (т.е. тех, которые не входят во множество параметров M), а также значения всех свободных переменных (иначе код функции F невозможно будет выполнить).
4. Для реализации этого намерения вы примените замыкание (иначе просто невозможно).

Остальное зависит от языка программирования и конкретной ситуации.
В любом языке основная задача замыкания - связать код функции и данные, с которыми она работает. Эту же задачу связывания кода и данных решают и объекты.
Ответ написан
@windsteppy
Trainee разработчик
Описание наиболее просто описать, как функцию (или метод, как назовешь - не важно), которая помнит о своем окружении - переменных, других функциях, причем чаще всего, это окружение недоступно в глобальном / ином контексте исполнения. Чаще всего, это функция внутри другой функции, по крайней мере, в контексте JS.
Код замыкания с пояснениями
Ответ написан
Комментировать
@programrails
Моё личное ИМХО:
1. Для того, чтобы выносить мозг нормальным людям при собеседованиях. Это их основная и главная область применения.
А ещё для динамического хранения данных. Смысловой аналог функции malloc в языке СИ, только более извращённо-вывернутый - "недовернувшаяся функция" (т.е. зависшая в памяти по сути). Человек, подвешенный за кишки. Отличие от malloc в том, что malloc просто выделяет кусок памяти под данные - а тут кусок памяти выделен под "данные + их некий обработчик" в одном флаконе.
2. Если говорить о веб-разработке - то на фронтэнде. Если не могут или не хотят хранить данные по-человечески - в куках, локальном хранилище, БД.

Насколько мне известно, бэкэндеру это вообще не нужно - только фронтэндеру. Ведь на бэкэнде всегда есть БД - и эти извраты ни к чему.
Ответ написан
DanielDemidko
@DanielDemidko
Программист
Всё просто. Замыкание это когда мы возвращаем из одной функции, назовём её глобальной, другую функцию, вложенную в первую.
Вложенная функция может в своей работе использовать внутренние переменные глобальной функции.
Замыкания есть не только в JS.
Ответ написан
Комментировать
miraage
@miraage
Старый прогер
1) чтобы сохранить переменные для будущего использования
2) посредством вызова функции, которая вернет другую новую функцию.
Ответ написан
Комментировать
@undefined_title
Это когда ты при объявлении функции имеешь доступ к переменным окружающей функции, именно и для этого доступа к переменным замыкание и используется
Ответ написан
Комментировать
@lemix85
Я бы сказал так. Например, когда в теле функции используется переменная объявленная в вышестоящей функции, то переменная будет удерживаться до тех пор пока не отработает внутренняя функция - т.е. внутрення функция замкнёт на себя переменную.
Например (setTimeout иллюстрирует любую асинхронную операцию):

function func1() {
    var myVar1 = 100;
    setTimeout(function() {
         console.log(myVar);
    }, 1000); 
}
func1();


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

Использовать можно, например, для создания колбэков с сохранением контекста:

/// Некорректный вариант, выведет 3 3 3
for(var i = 0; i < 3; i++) {
    setTimeout(function() { console.log(i) }, 1000); // Потому что на момент вызова колбэка цикл уже отработает и значение i будет максимальным
}


/// Выведет 0 1 2 т.к. текущее значение переменной i для каждой итерации передано аргументом в функцию в которой его замкнула другая функция
for(var i = 0; i < 3; i++) {
    var cb = (function(value) { 
        return function() { console.log(value) };
    })(i);
    setTimeout(cb , 1000);
}


Последний код делает то, что сегодня уже можно сделать с помощью bind (но в моё время bind'а не было):
for(var i = 0; i < 3; i++) {
    setTimeout(function() { console.log(this); }.bind(i) , 1000);
}
Ответ написан
Stalker_RED
@Stalker_RED
Ответ написан
Комментировать
solotony
@solotony
покоряю пик Балмера
1. Для чего замыкание существуют?


замыкания существуют для связывания функции с некоторым набором параметров

2. В каких условиях они создаются?


они создаются при определении функции (замыкания) внутри другой (внешней) функции, при этом переменные внешней функции будут тем самым привязываемым набором параметров.
Ответ написан
Комментировать
@Flicker
*-coder
Советую глянуть https://youtu.be/RPuFz93Gvpk
Ответ написан
Комментировать
Замыкание это функция и доступные ей внешние переменные
Переменная недоступна для функции (находится в соседней функции) - замыкания нет
Вынесли объявление переменной в область видимости выше - замыкание появилось
Ответ написан
Комментировать
Randel
@Randel
Developer
В PHP например есть функция array_map($a, $b) - каждый элемент массива $b обрабатывается функцией $a. Реализация callback тащемта.

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

Я ничего не перепутал?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы