我有一个代码: Demo jsFiddle
循环三次,每次创建一个返回循环序列号的新函数。
我希望看到循环序列inser到数组: 0,1和2.
a[i] = function() {
return i;
}
一切看起来都很正常但是当我尝试打印数组时我得到了
resualt:
arr[0] is =>function () { return i; }
arr[1] is =>function () { return i; }
arr[2] is =>function () { return i; }
代码:
function f() {
var a = [];
var i;
for (i = 0; i < 3; i++) {
a[i] = function() {
return i;
}
}
return a;
}
var arr = f();
for (var index = 0; index < arr.length; index++) {
document.write("<b>arr[" + index + "] is </b>=>" + arr[index] + "<br>");
}
为什么我没有得到resualt 0,1和2. ?
很多人。答案 0 :(得分:3)
因为a[i]
是函数,而不是函数的返回值。所以基本上你用三个函数体来填充你的数组,所以当你检索它们中的任何一个时,你就会回到函数的主体。您可以尝试a[i].call()
来调用返回的函数,但是每次调用都会得到3,这与Pointy在注释中指出的内容一致。因为这是调用循环时的最后一个值,所以在循环停止之前我变为3
请参阅the fiddle
答案 1 :(得分:1)
我想我理解为什么你期望所有数组元素都返回构造函数时的值i
。这不是一个巨大的飞跃,但每个功能共享一个范围。这些值没有链接到创建的函数,它的范围超过了“mother”函数。在此范围内,有一个名为i
的变量递增,直到它为3
。你唯一可以做的,如果你真的,真的想要使用一个闭包是这样的:
function f()
{
var a = [];
var i;
for (i = 0; i < 3; i++)
{
a[i] = (function(currentI)
{//create a separate scope, pass current value of i to it
return function()
{
return currentI;
}
})(i);
}
return a;
}
var arr = f();
for (var index = 0; index < arr.length; index++)
{
document.write("<b>arr[" + index + "] is </b>=>" + arr[index]() + "<br>");
}
这会产生预期结果as you can see here
答案 2 :(得分:1)
只是为了记录,如果你真正想要一个包含三个函数的数组,其中每个函数都返回i
的值,就像创建函数时一样,你只需要传递将功能分配给i
时,在a[i]
的副本中:
function f() {
var a = [];
var i;
for (i = 0; i < 3; i++) {
a[i] = (function(n) {
return function() {
return n;
};
}(i));
}
return a;
}
var arr = f();
for (var index = 0; index < arr.length; index++) {
document.write("<b>arr[" + index + "]() is </b>=> " + arr[index]() + "<br>");
}
输出:
arr [0]()is =&gt; 0
arr [1]()是=&gt; 1
arr [2]()is =&gt; 2