【问题标题】:A variable in a loop - how to fix it in my case? [duplicate]循环中的变量 - 在我的情况下如何修复它? [复制]
【发布时间】:2016-03-07 17:07:18
【问题描述】:

我在函数内部的循环中有一个变量:

function myHandler() {
  for (var i = 0; i < items.length; i++) {
    var currItem = items[i];

    myObj.doSomething(function(data) {
      console.log("ok");
      console.log("My currItem id: " + currItem.id); // the last one of all in items
    }, function(e) {
      console.log("error");
      console.log("My currItem id: " + currItem.id); // the last one of all in items
    });
}
console.log() 中的

currItem.id 每次 等于 items 中的最后一项。明显地。我试图通过这个来解决这个问题:

function myHandler() {
  for (var i = 0; i < items.length; i++) {
    var currItem = items[i];
    var currItem = (function(i2) {
      return items[i2];
    })(i);

    myObj.doSomething(function(data) {
      console.log("ok");
      console.log("My currItem id: " + currItem.id); // the last one of all in items
    }, function(e) {
      console.log("error");
      console.log("My currItem id: " + currItem.id); // the last one of all in items
    });
}

仍然没有成功。为什么以及如何解决?

【问题讨论】:

  • @Mario:错了;这正是你的问题。通过调用函数填充变量不会改变该变量的捕获方式。
  • 是的,看来您没有正确应用修复程序...更容易使用forEach
  • @Mario:看看我链接的另一个副本,我在其中详细解释了 iife 的放置位置。这有帮助吗?
  • @SLaks,这就是我要问的:如何解决它?毕竟睁大眼睛。

标签: javascript


【解决方案1】:

像这样使用闭包:

被返回的内部函数会记住创建它的环境。

function myHandler() {
  for (var i = 0; i < items.length; i++) {
    var currItem = items[i];

    myObj.doSomething((function(currItem) {
      return function(data) {
        console.log("ok");
        console.log("My currItem id: " + currItem.id);
      }
    })(currItem), (function(currItem) {
      return function(e) {
        console.log("error");
        console.log("My currItem id: " + currItem.id);
      }
    })(currItem));
  }
}

或者:

使用[].forEach,因为每个迭代器回调都有自己的上下文,不会被下一次迭代覆盖..

【讨论】:

    【解决方案2】:

    如果 doSomething 方法是异步的,这意味着回调在 for 循环之后运行,那么 currItem 将始终是最后一个。

    原因是闭包,回调函数有一个闭包,其中包含函数执行所需的所有信息,包括对变量 currItem 的引用。

    因为它是一个引用,所以当循环结束时 currItem 的值是最后一项,然后才会调用回调。

    修复它的最简单方法是将 for 循环的内部调用移动到一个函数,该函数将接受变量 currItem 作为参数。这样变量就不会改变了。

    你可以像这样使用数组的 forEach 函数来做到这一点:

    items.forEach(function(currItem){
    ....
    });
    

    【讨论】:

      猜你喜欢
      • 2010-11-12
      • 2012-06-29
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 1970-01-01
      • 2022-11-03
      • 2017-01-28
      相关资源
      最近更新 更多