JavaScript - 为什么这个闭包不保存参数

JavaScript - Why does this closure not hold parameters?

本文关键字:保存 参数 闭包 为什么 JavaScript      更新时间:2023-09-26

我正在阅读一篇关于闭包如何工作的文章。除了那篇文章中的第 5 节之外,我几乎都理解了所有内容。

它通过此示例讨论闭包如何与循环一起工作:

function buildList(list) {
  var result = [];
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
  return result;
}
function testList() {
  var fnlist = buildList([1,2,3]);
  // using j only to help prevent confusion - could use i
  for (var j = 0; j < fnlist.length; j++) {
    fnlist[j]();
  }
}
testList();

出现三个警报,每个警报都说 item3 未定义。我确实明白为什么它说item 3.buildList函数的闭包包含对item引用,它不保存实际值。

我不明白的是为什么list[i]result.push...行的每个警报中都以undefined的形式返回。该闭包是否仍然保留了list参数?

该闭包不是仍然保留了list参数吗?

是的。但是i的值将等于list.lengthlist[list.length]undefined.如果一个数组的长度3,那么最高可访问的索引是2,而不是3

var arr = [1,2,3];
console.log(arr[2]); // 3
console.log(arr[3]); // undefined

相关:循环中的JavaScript闭包 - 简单的实际示例

buildList它的内部匿名函数在一定程度上共享上下文。更改i ,就像在 for 循环中所做的那样,会为即使在事后创建的所有创建的匿名函数更改它。将匿名函数从:

function() {alert(item + ' ' + list[i])}

像这样:

(function(i){return function() {alert(item + ' ' + list[i]);};})(i)

这会导致在创建时创建 i 值的副本,并将其分配给另一个不同的i,该覆盖返回的匿名函数上下文中的外部i,同时仍允许动态访问itemlist