我一直在读一本关于JavaScript的书,作者已经触及几页关闭的主题。在一个页面上,他显示了以下示例:
function wrapElements(a) {
var result = [], i, n;
for (i = 0, n = a.length; i < n; i++) {
result[i] = function() { return a[i]; };
}
return result;
}
var wrapped = wrapElements([10, 20, 30, 40, 50]);
var f = wrapped[0];
现在,他说人们可能希望 f(); 返回 10 ,但它实际上会返回 undefined 。
这就是他所说的:
程序中的错误来自程序员的事实 显然期望该功能在当时存储 i 的值 嵌套函数已创建。但事实上,它包含一个参考 到我。由于在创建每个函数后i的值发生了变化,因此 内部函数最终会看到 i 的最终值。 [...]每个人 循环的迭代递增 i 直到它运行结束 数组,当我们实际调用其中一个闭包时,它会查找 数组的索引5并返回 undefined 。
但我无法理解他的解释。我再次阅读他之前关于闭包的解释(并且认为我理解它们 - 但显然,我似乎没有)并且我已经在互联网上搜索关于闭包的更多信息。我仍然无法理解为什么 f(); 会返回 undefined 。
在循环的每次迭代中都不会创建和调用匿名函数;因此,它不会查找所有索引而不仅仅是索引5吗?或者我误解了什么?
任何人都可以帮助我吗?感谢。
答案 0 :(得分:2)
循环中创建的所有小函数共享该公共变量i
。当i
循环结束时for
的值是多少? 5
。
调用这些函数时,i
仍 5
,a[5]
为undefined
。
这是创建函数的循环:
for (i = 0, n = a.length; i < n; i++) {
result[i] = function() { return a[i]; };
}
创建的每个函数都包含对i
的引用,表示“返回与当前值i
对应的数组元素”,其中当前表示当前的当前值该函数实际上是调用。 JavaScript不会为这些函数保留一些“冻结”状态,它会保留封闭函数的实际范围。在该范围内,变量i
仍然是同一个旧的快乐自我,并且只要循环中创建的任何函数查询其值,它就是5
。