关于外部变量的JavaScript和闭包

时间:2015-08-18 15:30:25

标签: javascript variables reference closures

我一直在读一本关于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吗?或者我误解了什么?

任何人都可以帮助我吗?感谢。

1 个答案:

答案 0 :(得分:2)

循环中创建的所有小函数共享该公共变量i。当i循环结束时for的值是多少? 5

调用这些函数时,i 5a[5]undefined

这是创建函数的循环:

  for (i = 0, n = a.length; i < n; i++) {
    result[i] = function() { return a[i]; };
  }

创建的每个函数都包含对i的引用,表示“返回与当前值i对应的数组元素”,其中当前表示当前的当前值该函数实际上是调用。 JavaScript不会为这些函数保留一些“冻结”状态,它会保留封闭函数的实际范围。在该范围内,变量i仍然是同一个旧的快乐自我,并且只要循环中创建的任何函数查询其值,它就是5