2010-07-20 2 views
13

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

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

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

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

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

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

+7

Посмотрите, пожалуйста, на большую партию ответов: http://stackoverflow.com/questions/111102/how-does-a-javascript-closure-work –

ответ

7

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

0

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

+0

Да, но я все же не видел сценарий, где все остальное не удалось, и закрытие было единственной вещью, которая могла бы сделать трюк – gath

+0

@gath - да, они делают. Многие из этих примеров - это функции, которые имеют другие функции в качестве возвращаемого значения. Если вы вызываете внешнюю функцию, сохраните ссылку на возвращаемую функцию, а затем вызовите возвращенную функцию в какой-то более поздний момент, эти примеры не могут работать без закрытия. –

+0

@gath: Все может быть написано на ассемблере. Закрытия не были изобретены для решения проблем, которые никогда не могли быть решены раньше, поэтому вы не найдете проблем, которые могут быть решены только с помощью закрытий. Они делают некоторые проблемы намного проще для решения, и если вы перейдете к этим примерам с учетом этого, они могут начать иметь для вас больше смысла. –

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, уничтожая ее переменные. Однако, поскольку у нас есть анонимная функция с использованием текста, мы должны отслеживать эту переменную. Это может быть достигнуто по значению или по ссылке, в зависимости от языка (сохранение переменной в активном состоянии (с возможностью ее модификации впоследствии или копирование ее значения при создании функции)).

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

0

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

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

2

«Закрытие - объект бедного человека. Объект - закрытие бедняка». (Извините, я забыл об источнике).

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

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

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

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

+0

это отличная аналогия – qodeninja

Смежные вопросы