2013-05-16 3 views
5

Эй я наткнулся на это видео на YouTube http://www.youtube.com/watch?v=KRm-h6vcpxsЕсть функция возврата необходимо назвать укупорочное

, который в основном объясняет IIFEs и закрытия. Но я не понимаю, нужно ли мне возвращать функцию, чтобы назвать ее закрытием.

E.x.

function a() { 
    var i = 10; 
    function b() { 
     alert(i); 
    } 
} 

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

return function b(){alert(i);} 
+0

+1 to @dystroy ответить. Вам не нужно вызывать другую функцию внутри функции, чтобы закрыть первую. Это похоже на людей, которые используют «return null». Вам не нужно возвращать что-то, чтобы закончить функцию. Просто закройте его: P – DaGLiMiOuX

+0

это то, что я думал, но в видео это определение было дано так, поэтому я думал, что подтвержу то же самое – Nav

+0

@DaGLiMiOuX - OP спрашивает о [закрытиях] (http://en.wikipedia.org/ wiki/Closure_ (computer_science)), не говоря о том, как закончить функцию. – nnnnnn

ответ

3

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

+0

Но в примере OP 'b()' фактически не вызывается, и если он _was_ вызван изнутри 'a()' когда 'a()' завершено все это может быть собрано в мусор, поскольку нет никакой надежной ссылки на любую из переменных в этой области. Закрытие действительно действительно становится актуальным для программиста, если вы начинаете передавать ссылки на функции вокруг (так или иначе). – nnnnnn

+0

@nnnnnnnЭто не обязательно верно, я думаю, что я хочу напечатать или добавить значения в журнал непосредственно из функции b(), и я не вижу смысла в возвращении функции ... что вы думаете ??? – Nav

1

К definition of closure достаточно ссылки на функцию с ее областью. Таким образом, в основном создание функции делает его закрытие, так как именно там ссылка создается в JavaScript :-)

Тем не менее, для использования этой функции мы вызова функции от различного масштаба, чем это было определяемый в - это то, на что называет термин «использование закрытия» на практике. Этот показатель может быть более низкой или более высокой сферы - и функция не обязательно должна быть return ред от функции, в которой она была определена в

Некоторые примеры:

var x = null; 

function a() { 
    var i = "from a"; 
    function b() { 
     alert(i); // reference to variable from a's scope 
    } 
    function c() { 
     var i = "c"; 
     // use from lower scope 
     b(); // "from a" - not "c" 
    } 
    c(); 

    // export by argument passing 
    [0].forEach(b); // "from a"; 
    // export by assigning to variable in higher scope 
    x = b; 
    // export by returning 
    return b; 
} 
var y = a(); 
x(); // "from a" 
y(); // "from a" 
1

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

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

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

var globalF; // a global variable 

function x() { // just to have a local scope 

    var local; // a local variable in the scope 

    var f = function(){ 
    alert(local); // use the variable from the scope 
    }; 

    globalF = f; // copy a reference to the function to the global variable 

} 

x(); // create the function 
globalF(); // call the function 

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

4

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

Придумайте закрытия как Uncle Scrooge:

enter image description here

дядюшка Скрудж скрягой. Он никогда не отпустит свои деньги.

Аналогичным образом закрытие также является скрягой. Он не отпустит свои переменные, пока не умрет сам.

Например:

function getCounter() { 
    var count = 0; 

    return function counter() { 
     return ++count; 
    }; 
} 

var counter = getCounter(); 

Смотрите эту функцию counter? Тот, который возвращается функцией getCounter? Эта функция - скряга. Он не отпустит переменную count, хотя переменная count принадлежит вызову функции getCounter и этот вызов функции завершен. Поэтому мы вызываем counter замыкание.

См. Каждый вызов функции может создавать переменные. Например, вызов функции getCounter создает переменную count. Теперь эта переменная count обычно умирает, когда заканчивается функция getCounter.

Однако функция counter (которая может получить доступ к переменной count) не позволяет ей умереть при завершении вызова getCounter. Это связано с тем, что функция counter нуждается в count. Следовательно, он сможет только умереть после того, как он сам умрет.

Теперь действительно интересно отметить, что counter рождается внутри звонка до getCounter. Следовательно, даже counter должен умереть, когда вызов getCounter заканчивается - но это не так. Он живет даже после того, как вызов getCounter заканчивается, потому что он пропускает область действия (время жизни) getCounter.

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

var counter; 

function setCounter() { 
    var count = 0; 

    counter = function counter() { 
     return ++count; 
    }; 
} 

setCounter(); 

Здесь функция сестра getCounter (которая точно называется setCounter) назначает новый counter функцию глобальной counter переменной. Следовательно, внутренняя функция counter выходит за рамки setCounter, чтобы стать закрытием.

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

Для получения более подробной информации читайте этот ответ: https://stackoverflow.com/a/12931785/783743

+2

+1 для создания сообщения, более интересного с фотографиями. Несчастные люди - заблудились! :) – Jimbo

+0

@Jimbo - Спасибо. Что касается человека, который меня превзошел - если вы читаете это, я могу знать, почему вы считаете, что мой ответ заслуживает отрицательного голоса? –

+0

+1 для изображения lol ... я люблю donald duck;) – Nav

0

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

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

a) sicp: в абстрактной алгебре, где набор элементов называется замкнутым под действием, если применение операции к элементам в наборе вызывает элемент, который снова является элементом множества.Сообщество Lisp также (к сожалению) использует слово «закрытие» для описания совершенно несвязанной концепции: закрытие представляет собой метод реализации для представления процедур со свободными переменными.

b) wiki: замыкание является функцией первого класса, которая фиксирует лексические привязки свободных переменных в определяющей среде. Как только он захватил лексические привязки, функция становится замыканием, потому что она «закрывает» эти переменные ».

c) книга тигра: структура данных в куче (вместо стека), которая содержит оба указателя функций (MC) и указатель окружения (EP), представляющий функциональную переменную;

d) on lisp: комбинация функции и набора переменных привязок называется замыканием; замыкания - это функции с локальным состоянием;

e) Видео google i/o: похоже на экземпляр класса, в котором данные (экземпляр obj) инкапсулируют код (vtab), где в случае замыкания код (функциональная переменная) инкапсулирует данные.

f) инкапсулированные данные являются частными для функциональной переменной, подразумевая, что закрытие может использоваться для скрытия данных.

g) закрытие в нефункциональных языках программирования: обратный вызов с файлом cookie в C является аналогичной конструкцией, а также «закрытие» glib: закрытие glib представляет собой структуру данных, инкапсулирующую аналогичные вещи: указатель обратного вызова сигнала, cookie частные данные и деструктор замыкания (поскольку в C нет GC).

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

i) Грег Майклсон ($ 10.15): (в реализации lisp) закрытие - это способ идентифицировать взаимосвязь между свободными переменными и лексическими связанными переменными, когда необходимо (как это часто необходимо) вернуть значение функции со свободными переменными заморожен до значений из определяющей области.

j) histroy and этимология: Питер Дж. Ландин определил термин закрытие в 1964 году как имеющий часть среды и контрольную часть, используемую его машиной SECD для оценки выражений. Джоэл Мозес приписывает Ландину введение термина «замыкание» для обозначения лямбда-выражения, открытые привязки которого (свободные переменные) были закрыты (или связаны) лексической средой, что привело к закрытому выражению или замыканию. Это использование впоследствии было принято Суссманом и Стил, когда они определили Схему в 1975 году и получили широкое распространение.

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