for循环中的javascript闭包

时间:2011-12-28 21:11:33

标签: javascript closures

  

可能重复:
  Javascript closure inside loops - simple practical example
  Javascript: closure of loop?

所以我希望结果是1,2,3而不是3,3,3。如何设置上下文/范围,以便作业使用正确范围的“i”?

function buildJobs(list) {
  var jobs = [];
  for (var i = 0; i < list.length; i++) {
    var item = list[i];
    jobs.push( function() {alert(item)} );
  }
  return jobs;
}

function testJobs() {
  var jobs = buildJobs([1,2,3]);
  for (var j = 0; j < jobs.length; j++) {
    jobs[j]();
  }
}

3 个答案:

答案 0 :(得分:1)

用另一个立即执行的函数包装内部函数并接收i作为参数:

function buildJobs(list) {
  var jobs = [];
  for (var i = 0; i < list.length; i++) {
    var item = list[i];
    (function(i) {
      jobs.push( function() {alert(list[i])} );
    })(i);
  }
  return jobs;
}

您现在正在关闭包装函数本地的i,这是每次迭代中的一个不同变量。 (在原始配置中,每个内部函数都关闭相同的变量(在执行任何函数时,其值为3。)

答案 1 :(得分:1)

当循环生成函数时,它们都共享对同一变量范围的访问。在给定范围内,同一名称上只能有一个变量。所以他们都在循环中使用i,并在执行时使用i的当前值。循环运行后,它将始终为3。

function buildJobs(list) {
  var jobs = [];
  for (var i = 0; i < list.length; i++) {
    (function(i) {
      var item = list[i];
      jobs.push( function() {alert(item)} );
    })(i);
  }
  return jobs;
}

因此,引入一个新范围,仅为该迭代捕获i的当前值。现在,您为每个生成的函数创建了一个新范围,每个函数都具有i的不同值。

答案 2 :(得分:0)

function buildJobs(list) {
    var jobs = [];

    list.forEach( function( item ){
        jobs.push( function(){
            alert(item);
        });
    });

    return jobs;
}

forEach