Закрытие создается благодаря тому факту, что вы возвращаете функцию, имеющую доступ к локальной переменной x
, которая была определена как единственный член списка формальных параметров.
Таким образом, функции, хранящиеся в a[i]
, закрылись вокруг своего уникального x
, который находился в той же области видимости, и как таковой, имеют к нему доступ. Поскольку эта переменная доступна только этой функции, которая была передана из функции, вызывающей саму себя, у вас есть замыкание.
Я бы отметил, что было бы лучше, если бы вы не использовали здесь самозапускающуюся анонимную функцию, поскольку она не нужна и добавляет накладные расходы. Вместо этого объявите именованную функцию и вызовите ее.
function foo()
{
var a = [];
function retain_i(x)
{
return function()
{
return x;
}
}
for(var i = 0; i < 3; i++)
{
a[i] = retain_i(i);
}
return a;
}
РЕДАКТИРОВАНИЕ: Чтобы быть более конкретным на ваш вопрос:
замыкание создается при вызове (i) на каждой итерации ...
Нет, это не создает закрытие. Закрытие создается, когда вы возвращаете функцию, которая закрылась вокруг параметра x
, который в противном случае был бы недоступен вне функции, вызывающей себя.
Если бы вы не вернули эту функцию, у вас не было бы закрытия.
Итак, как вы можете видеть из приведенного мною примера кода, определение / объявление функции не создает замыкание. Скорее выполнение функции, которая выходит из нее какой-то другой функции, которая имеет доступ к недоступным в противном случае переменным, создает замыкание.