Закрытие создается в силу того факта, что вы возвращаете функцию, которая имеет доступ к локальной переменной x
, которая была определена как единственный член списка формальных параметров.
Таким образом, функции, хранящиеся в a[i]
, закрылись вокруг их уникального x
, который был в том же объеме, и, таким образом, имеют к нему доступ. Поскольку эта переменная доступна только этой функцией, которая была передана из функции self invoking, у вас есть закрытие.
Я хотел бы отметить, что было бы лучше, если бы вы не использовали самоназывающую анонимную функцию здесь, поскольку она не нужна и добавляет дополнительные служебные данные. Вместо этого объявите именованную функцию и вызовите ее.
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;
}
EDIT: Чтобы быть более точным на ваш вопрос:
замыкание создается, когда я звоню (я) на каждой итерации ...
Нет, это не создает замыкания. Закрытие создается, когда вы возвращаете функцию, которая закрыта вокруг параметра x
, что было бы недоступно в других местах вне функции самозапуска.
Если вы не вернули эту функцию, у вас не было бы закрытия.
Так как вы видите из примера модифицированного кода, который я дал, определение/объявление функции не создает замыкание. Скорее выполнение функции, которая выдает из нее какую-то другую функцию, имеющую доступ к недоступным другим переменным, создает закрытие.
В соответствии с моделью среды закрытие создается * при определении функции *. Не имеет значения, переживает ли закрытие переживающий контекст или нет. – EFraim 2010-12-06 22:22:23