这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