クロージャは、仮パラメータリストの唯一のメンバーとして定義されたローカル変数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;
}
EDIT:は、あなたの質問に具体的には:私はすべての繰り返しで(i)を呼び出すとき
閉鎖が作成されます...
いいえ、これはクロージャを作成しません。 がを返したときにクロージャが作成されるのは、x
パラメータの周りで閉じた関数で、それ以外の場合は自己呼び出し関数の外部ではアクセスできません。
この関数を返さなかった場合は、クロージャはありません。
私が与えた修正されたコード例からわかるように、関数の定義/宣言はクロージャを作成しません。むしろアクセスできない変数にアクセスできる他の関数を渡す関数の実行は、クロージャを作成します。
環境モデルによれば、関数*を定義するとクロージャが作成されます。クロージャーが生き残った文脈を越えるかどうかは関係ありません。 – EFraim