【问题标题】:javascript closure in a for loop [duplicate]for循环中的javascript闭包[重复]
【发布时间】:2011-12-28 21:11:32
【问题描述】:

可能重复:
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]();
  }
}

【问题讨论】:

  • 不是完全相同的副本,而是相同的想法。
  • @hvgotcodes 有超过 9000 个完全相同的副本,所以如果那个不是真的没关系:D
  • 准确地说,这个问题被问了多少次令人惊讶......

标签: javascript closures


【解决方案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,它在每次迭代中都是不同的变量。 (在您的原始配置中,每个内部函数都关闭了 same 变量(在任何函数执行时,其值为 3。)

【讨论】:

    【解决方案2】:

    当循环生成函数时,它们都共享对相同范围变量的访问。并且在给定范围内只能有一个同名变量。所以它们都使用循环中的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 值。

    【讨论】:

      【解决方案3】:
      function buildJobs(list) {
          var jobs = [];
      
          list.forEach( function( item ){
              jobs.push( function(){
                  alert(item);
              });
          });
      
          return jobs;
      }
      

      forEach

      【讨论】:

        猜你喜欢
        • 2018-12-26
        • 2011-01-12
        • 2012-09-29
        • 1970-01-01
        • 2012-12-15
        • 2020-10-18
        • 1970-01-01
        • 2016-05-03
        • 1970-01-01
        相关资源
        最近更新 更多