Почему у нас есть закрытие в JavaScript?

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

Я начинаю понимать эту концепцию, но чем больше я понимаю, тем больше я продолжаю задаваться вопросом, почему мы должны их использовать.

Пример, подобный этому, заставляет меня понять концепцию, но не дает мне спросить, есть более простой способ сделать это!

function sayHello(name) {
   var text = 'Hello ' + name;
   var sayAlert = function() { alert(text); }
   sayAlert();
}
sayHello('Gath');

Просто интересно, почему мне нужно сохранить локальную переменную? после выхода функции?

Где я могу получить примеры, демонстрирующие решения, реализованные при закрытии, и что ничто другое не сработало бы, кроме закрытия?

Ответ 1

Closures добавляют выразительную силу к языку. Есть некоторые шаблоны, которые могут быть реализованы очень легко из-за закрытия. Несколько примеров, которые приходят на ум, включают в себя:

Ответ 2

Закрытие - это функция со всей необходимой ей средой, которая должна быть выполнена. В javascript он создается при анонимной функции (= lambda), используя переменную из внешней области.

Вы можете лучше понять, почему с таким кодом:

function foo()
{
  var text = computeFromOutside();
  // ... other lines of code
  return function(otherText) { return text + otherText; }
}

bar = foo();

function baz(fun)
{
  return fun("some text");
}

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

Надеюсь, это поможет!

Ответ 3

"Закрытие - это плохой человек. Объект - закрытие человека". (Извините, я забыл источник).

Иногда нам нужны переменные, которые нужны только блоку кода one. Мы помещаем этот блок кода в функцию и имеем эти переменные в качестве локальных переменных для этой функции.

Иногда нам нужны переменные, которые необходимы all для функций/блоков кода в программе. Мы можем иметь эти переменные как глобальные переменные.

Иногда нам нужны переменные, которые нужны некоторым функциям/блокам кода. Например, у нас есть организация под названием Sales, и мы хотим объединить весь наш код, связанный с продажей. Таким образом, у нас есть группа функций и группа переменных, которые касаются продаж. Мы можем объединить эти функции и переменные в объект, чтобы они были изолированы (как функции, так и переменные) от других частей кода.

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

Ответ 4

Выбранный вами пример отображается на этой странице, поэтому я предполагаю, что вы взяли его оттуда. Вы рассмотрели все другие примеры, которые он дает? Они объясняют мотивы закрытия, лучше, чем я мог.

Ответ 5

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

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