2009-11-26 10 views
65

Я понимаю, что такое закрытие, но у меня есть некоторые проблемы с grokking, на что ссылается термин closure. Я видел термин, используемый во многих веб-сайтах, но редко согласен с его фактическим определением.Что именно означает «закрытие» в JavaScript?

  • Являются ли это переменными, которые хранятся на стеке стека?
  • Это функция, которая возвращается?
  • Является ли это объем внешней функции?
  • Является ли это объем внутренней (возвращенной) функции?
  • Возможно ли это концепция хранения переменных в стеке после возврата функции?

Может ли кто-нибудь сказать мне точно, к чему относится closure?

+8

+1 потому что вы спрашиваете удобные вопросы – alex

+0

Просмотрев полдюжины объяснений .. этот выглядит довольно хорошо для разрушения основных соображений http://www.sitepoint.com/javascript-closures-demystified/ – gnB

ответ

43

От JavaScript Closures

Два в одном предложении резюме:

Замыкание это локальные переменные для функции - хранится в живых после того, как функция вернулась, или

Замыкание это стек-кадр, который равен , не освобождается при возврате функции . (Как будто 'стек-кадр' были malloc'ed вместо того, чтобы быть на стека!)

Очень хорошая статья о закрытий

Javascript Closures

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

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

Хороший пример здесь

JavaScript, time to grok closures

+0

Я написал набор статей по этому вопросу с графическим объяснения. Читайте главы-4 и 5 здесь: https://rahuldotout.wordpress.com/2011/05/15/professional-javascript-part-4-scopes-and-scope-chain/ – rahulmohan

2

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

function delay_message(msg) 
{ 
    setTimeout(function closure() { alert(msg); }, 1000); 
} 

В этом случае, указанное выше function closure определен в пределах тела delay_message, но определение функции - а также родительской функции переменной msg - переживет сферу delay_message вызов функции.

+0

, так что вы говорите, что закрытие Внутренняя функция? –

+0

«Закрытие» представляет собой комбинацию функции и ее состояния. I.e., внутренняя функция, привязанная к набору локальных переменных из внешней функции. – intgr

+0

Внутренняя функция ('функция закрытия') создается во время разбора, но в этот момент нет закрытия. Закрытие создается как 'function delay_message' выполняется и связывает его состояние с' функцией закрытия'. – intgr

6

Это функция, которая «хранит» ссылку или ссылки на что-то в другой области. Например:

var myArrayOfFunctions = []; 

for(var i = 0; i<3: i++) 
{ 
    //Note how the function being defined uses i, 
    //where i lives in the parent's scope, this creates a closure 
    myArrayOfFunctions[i] = function(a) { return a + i;}  
} 

myArrayOfFunctions[0](5); //Prints 8 WTF! 
myArrayOfFunctions[1](5); //8 again 
myArrayOfFunctions[2](5); //Well, this 8 was expected 

Это происходит потому, что, когда функция «создаются», они не копируют значение I, они содержат ссылку на I, поэтому, когда мы называем функции, которые они используют текущее значение I которая 3.

Here is a graphical explanation.

4

для меня замыкания в JS позволяет сделать следующее.
«a» остается доступным во внутренней функции при добавлении к «b», хотя он объявлен снаружи.

function adder(a){ 
    return function(b){ 
    return a + b; 
    }; 
} 
var add5 = adder(5); 
alert(add5(10)); 

Для экстремального использования JS закрытия, вы можете посмотреть на source code из PURE библиотеки (шаблонизатор JS)

+2

Я знаю, для чего закрыты, но ваш ответ по-прежнему на самом деле не уточняет, что «закрытие» действительно относится к –

+0

. Мне понравился этот пример, поскольку он является меньшим, который я знаю, чтобы показать, что такое закрытие, и было самым показывая для меня, изучая функциональные JS. – Mic

+0

Получил ли вы этот пример из книги шаблонов JavaScript Stoyan Stefanov? –

1

По сути замыкание есть функция тела сомкнулись над его идентификаторы (переменные) в пределах своей локальной среды.

1

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

2

Рассмотрим следующий код, который создает замыкание с переменными а и б

closure=(function(){ 

    var a=3 
    var b=5 

return function(operation){ 
      return operation(a,b) 
     } 
}()) 


// The variables a and b are now part of the closure (They are retained even after the outer function returns) 


closure(function(x,y){return x+y}) // outputs 8 

closure(function(x,y){return x*y}) // outputs 15` 

Данный замыкание теперь может принимать любую функцию, которая работает на переменных а и б