Javascript循环中关闭问题

时间:2017-01-10 21:12:39

标签: javascript for-loop closures

过程:在我正在制作的游戏中,有一个 for 循环,它应该在数组中保存一个值。该值随每次迭代而变化。问题:当循环完成运行时,数组的每个元素都是相同的,都显示最新的值 我知道这个问题很常见,我在过去的两天里做了很多不同的调整并尝试解决它。​​

0)我尽可能地将事物分成不同的功能 1)我尝试用“let”定义我的循环计数器,以便它们具有本地范围 2)我尝试将我的赋值包装在一个自动执行的函数中,因此它会立即发生,在下一个循环迭代更改它之前保留currentOn的值。我的计数器是变量c。

(function(c2, currentlyOn2) {
  onAtSameTime[c2] = currentlyOn2;
  return 0;
})(c, currentlyOn);

3)我尝试了#2尝试添加了一个功能,它仍然没有保存currentOn的值。无论如何,这个选项对我来说不是一个好选项,因为重点在于我提前做了一些计算,所以我的游戏会有一个快速的动画循环。

onAtSameTime[c] = (function(currentlyOn2) {
  return function() {
    return currentlyOn2;
  };
})(currentlyOn);

我厌倦了对着这堵墙打我的头。谁能解释我做错了什么?

有关详细信息,请查看jsfiddle I made。问题区域位于第59行,使用简单的赋值:

onAtSameTime[c] = currentlyOn;

3 个答案:

答案 0 :(得分:1)

onAtSameTime[c] = currentlyOn;设置onAtSameTime[c]等于currentlyOn引用,因为currentlyOn是一个数组,而不是原始值。每次迭代都会更新该引用。您可以通过在将数组添加到onAtSameTime数组之前创建数组副本来解决此问题。像onAtSameTime[c] = [].concat(currentlyOn);之类的东西可以解决问题。

请参阅JSFiddle的这个分支:https://jsfiddle.net/L2by787y/

答案 1 :(得分:1)

您可以从currentlyOn制作副本以分配给onAtSameTime[c]。这会保留值,但不会保留对同一数组的引用。

onAtSameTime[c] = currentlyOn.slice(); // use copy

"use strict";
function log(text) {
    document.getElementById("logbox").innerHTML += JSON.stringify(text) + "<br>";
    return 0;
}

function whichSwitchesAreOn() {
    var currentlyOn = [],
        flickedSet,
        flickedOne,
        turningOnCheck;

    for (var c = 0; c < switchesToggled.length; c++) {
        flickedSet = switchesToggled[c];
        for (var d = 0; d < flickedSet.length; d++) {
            flickedOne = flickedSet[d];
            turningOnCheck = currentlyOn.indexOf(flickedOne);
            if (turningOnCheck == -1) {
                currentlyOn.push(flickedOne);
            } else {
                currentlyOn.splice(turningOnCheck, 1);
            }
        }
        log("currentlyOn: " + currentlyOn);
        onAtSameTime[c] = currentlyOn.slice(); // use copy
    }
    return 0;
}

var switchesToggled = [[0], [1, 2], [0], [2], []],
    onAtSameTime = [];

whichSwitchesAreOn();
log(onAtSameTime);
<div id="logbox"></div>

答案 2 :(得分:0)

你说你试过了吗?

你有没有让for循环中的currentOn = []?

  for(var c = 0; c < switchesToggled.length; c++) {
      let currentlyOn = [];