有人可以解释为什么document.write
部分总是输出10?
function creatFunctions() {
var result = new Array();
for (var i = 0; i < 10; i++) {
result[i] = function () {
return i;
}
}
return result;
}
var funcs = creatFunctions();
for (var i = 0; i < funcs.length; i++) {
document.write(funcs[i]() + "<br />");
}
我认为这个问题的答案比重复的问题更彻底,因此值得保留这篇文章。
答案 0 :(得分:9)
不确定
在for
循环中,您引用i
。您期望发生的是每个闭包在创建函数时获取i的快照,因此在第一个函数中它将返回0,然后是1,等等。
真正发生的是每个闭包都会获得对外部变量i
的引用,该变量会在i
循环中更新for
时不断更新。
所以,第一次通过循环,你得到一个返回i
的函数,此时它是0.下次你得到两个返回i
的函数,现在是1等等。
在循环结束时,i==10
,每个函数返回i
,因此它们都返回10.
更新以回答评论中的问题:
由于您在两个不同的上下文中使用i
,因此有点混乱。我会对您的代码进行一些微小的更改,以帮助说明正在进行的操作:
function creatFunctions() {
var result = new Array();
for (var i = 0; i < 10; i++) {
result[i] = function () {
return i;
}
}
return result;
}
var funcs = creatFunctions();
// NOTE: I changed this `i` to `unrelated_variable`
for (var unrelated_variable = 0; unrelated_variable < funcs.length; unrelated_variable++) {
document.write(funcs[unrelated_variable]() + "<br />");
}
...您在creatFunctions()
函数中创建的函数都返回i
。具体来说,它们返回您在for循环中创建的i
。
我已将其重命名为unrelated_variable
的另一个变量对关闭时返回的值没有影响。
result[i] = function () {
return i;
}
...与result[2] = 2
不同。这意味着result[2] = the_current_value_of_i
答案 1 :(得分:4)
因为您将i
引用为变量,当函数执行时,变量的值为10
。相反,您可以通过包装函数来创建i
的副本:
(function (i) {
result[i] = function () {
return i;
}
}(i));
答案 2 :(得分:3)
你在内部函数中返回的i
是在i
内声明的for(var i=0...)
- 它对于所有的i
是相同的result
中的函数
当你调用函数时,它的值是10(循环结束后)
要完成你想要的,你应该在匿名函数范围内声明另一个变量
答案 3 :(得分:1)
因为对“i”的引用是在您定义的闭包中加框(附上)。
result[i] = function () {
return i;
}
它只是引用了“i”var,它随着每次迭代而不断变化。
答案 4 :(得分:0)
<强>更新强>
这与定义变量上下文的函数作用域有关。
因此,在JavaScript中,没有块范围(this
关键字for
,if else
,while
,......)。
考虑到这一点,如果将var funcs
分配给函数 definition 调用,函数体(该函数内的var this
)将绑定到全局范围i
将到达for循环的末尾并保留在内存中。在这种情况下,i
为10。
不幸的是,由于函数范围将每个变量放在顶部,。var i
也是全局变量
虽然我一开始就完全错了,但我会立即纠正并冒昧地在demo中创建脚本的输出。