古き良きi
+スコープの問題です;)...解決策:
function init(list)
{
var item, result = [];
for (var i = 0; i<list.length; i++)
{
item = 'item' + list[i];
result.push((function(val, idx)
{//create this function with its own scope
return function()
{//return this function, which has access to val and idx
alert(val+' '+list[idx]);
};
}(i, item));//pass vals of i and item to function, and call it here (IIFE)
}
return result;
}
なんで?特定のスコープで作成されたすべての関数は、その上位のスコープで宣言された変数にアクセスできます。したがって、プッシュしresult
ている関数には、実際にi
、item
およびへのアクセスがありlist
ます。アクセス権はありますが、それらの変数の独自のコピーを所有していません。
for ループの反復ごとに、i がインクリメントされるため、0、1、2、3 になります。その値が 3 に達すると、その値がなくなる< list.length
ので、ループが終了します。しかし、作成している関数内では、未定義の にlist[i]
評価されます。list[3]
同じことが にも当てはまりますitem
。変数はinit
関数で宣言され、反復ごとに再割り当てされるため、作成された関数のどれを呼び出しても、最後に割り当てられたものを参照しますitem
: "item3"あなたの場合。
これを詳細に説明するかなり長い回答を投稿し、 tag-wikiにも多くの情報を追加しました。今のところ、次のように簡単にテストできます。
function init(list)
{
var j, result = [];
for (var i = 0; i<list.length; i++)
{
var item = 'item' + list[i];
result.push( function() { alert( item + ' ' +list[i] ) } );
for (j=0;j<=i;j++)
{
result[j]();
}
}
alert(i);
return result;
}
これにより、次のような警告が表示されます。
//i = 0
item1 1
//i = 1
item2 1
item2 2
//i=2
item3 1
item3 2
item3 3
//outside loops, alert i:
3