【问题标题】:node.js: closure in loopnode.js:循环中的闭包
【发布时间】:2014-10-10 10:08:29
【问题描述】:

我无法在闭包上挂起。一个非常简单的例子:

var array = [1,2,3];
var test = [0,0];
var result = [];
for (var i=1; i<=array.length; i++){    
    test[1] = i;
    result.push(test);
}
console.log(result);

如果我只是将“i”推入结果,它会输出“1,2,3”,但上面的方式我总是得到“[0,3],[0,3][0,3]”。这是为什么?我已经阅读了一些关于闭包的解释,但我似乎不理解这个系统,这使得在我的代码中很难找到额外的错误。难道没有比在函数中使用函数更简单的方法来解决上述问题吗(这似乎是我迄今为止发现的所有等效问题的解决方案)?

【问题讨论】:

  • 问题并不是真正的关闭问题,而是您对您推送的所有 3 个条目重复使用完全相同的测试实例,因此当您更改一个条目时,它们都会改变。您真正想通过在循环外声明一次测试来实现什么?
  • 您好 Joachim,感谢您的见解。你的第一句话已经对我有用了。

标签: node.js loops closures


【解决方案1】:

您正在将相同的实例写入结果,并且当您更改该实例中的参数时,结果中的所有实例都会更改。您需要创建单独的实例来保存数据,这里是说明正确方法的代码

var array = [1,2,3];
var test = [0,0];
var result = [];
for (var i=1; i<=array.length; i++){
    var z = [test[0], i];
    result.push(z);
}
console.log(result);

【讨论】:

    【解决方案2】:

    关键是当您在 JavaScript 中替换 Array 时,它不是复制,而是提供指向 Array 的链接。 所以

    var testArray = [1,2,3];
    var copy = testArray;
    copy[1] = 10;
    console.log(testArray); // [1,10,3]
    

    为避免这种情况,您可以通过 .concat() 或 .slice()“复制”数组

    var testArray = [1,2,3];
    var copy = testArray.concat(); // or Array.slice(0)
    copy[1] = 10;
    console.log(testArray) // [1,2,3]
    

    所以你的代码是

    var array = [1,2,3];
    var test = [0,0];
    var result = [];
    for (var i=1; i<=array.length; i++){    
        test[1] = i;
        result.push(test.concat());
    }
    console.log(result);
    

    【讨论】:

    • 您正在使用变量名隐藏本机 Array 标识符,除非您有充分的理由,否则请不要这样做。
    • 感谢您的帮助,这正是我所需要的。我正在使用现有条目作为模板创建新条目,但不知道它只是一个链接(我这样做的方式)。
    • @Benjamin Grunbaum 你是对的,我没有运行代码,只是在这里直接写代码。我修复它。感谢您的评论
    猜你喜欢
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2018-06-10
    • 1970-01-01
    • 2012-12-15
    • 2021-10-27
    • 1970-01-01
    相关资源
    最近更新 更多