在嵌套for循环中添加属性会导致每个父for循环的值相同

时间:2016-10-05 12:22:45

标签: javascript arrays object for-loop

我有一个包含扑克牌信息的数组(cardInfo)。在下面的代码中添加了一个数组示例。由于每张卡可能有重复,我想使用此信息通过将其信息推送到该类型的每张卡(属性'frequency1')的新数组(drawPile)来创建卡片。

var common = 4;
var uncommon = 3;
var rare = 2;
var cardInfo = [
    {name:'Card A',frequency1:common,frequency2:rare,frequency3:0}, 
    {name:'Card B',frequency1:common,frequency2:uncommon,frequency3:0},
    {name:'Card C',frequency1:uncommon,frequency2:uncommon,frequency3:0}
];

var drawPile = [];
for (var cType = 0; cType < cardInfo.length; cType++) {
    for (var freq = 0; freq < cardInfo[cType].frequency1; freq++) {
        drawPile.push(cardInfo[cType]);
        console.log(drawPile.length - 1);
        drawPile[(drawPile.length - 1)].id = (drawPile.length - 1);
        console.log(drawPile[(drawPile.length - 1)]);
    }
}

然而,生成的控制台日志显示所有4张“Card A”牌都有id属性3,所有4张“Card B”牌都有id属性7,所有3张“Card C”牌都有id属性10.好像嵌套(freq)循环只在所有.push()命令运行之后才添加id属性。

更奇怪:当我在jsfiddle中运行此代码时,如果我首先运行它然后打开控制台日志,我可以复制这些结果,但是当我在控制台lof已经打开后运行它时,它可以工作如预期的那样。

如何确保每张卡都有唯一的标识符?

编辑:当我得到完全相同的结果时,如果我创建一个全新的for循环,专门用于添加this code中所见的id属性,那就更奇怪了。

2 个答案:

答案 0 :(得分:0)

围绕cardInfo集合循环,对于每个cardInfo实例,循环频率。从技术上讲,您在同一个cardInfo实例中的每个频率,因此从技术上讲,您为每个频率迭代更新相同的cardInfo实例。现在你的下一个语句将是,但我为每次迭代编写console.log。但是当您调试代码时,console.log输出正确,但是我不确定在没有调试的情况下运行它是否是这种情况。那你怎么解决这个问题呢?

在确定它正在为相关频率的每次迭代修改相同的实例后,我决定克隆该卡(我不是说这是一个好主意,但它证明了这个概念)。我通过使用:

实现了这一目标
JSON.parse(JSON.stringify(cardInfo[cType]));

同样,这不是实现这一目标的最佳方式,但突出了我认为问题所在。

我已将此更改应用于fiddle(我还简化了一些代码),如果您删除克隆,它会按照您目前的操作进行操作,但克隆时它会按预期运行它

我希望有帮助

答案 1 :(得分:0)

您正在将对象引用推送到循环中的drawPile数组。这就是为什么所有&#34;卡A&#34;卡具有与包含相同引用的数组相同的ID。你必须在推入循环之前克隆对象。您可以对代码进行以下更改。

  for (var freq = 0; freq < cardInfo[cType].frequency1; freq++) {
            drawPile.push(JSON.parse(JSON.stringify(cardInfo[cType])));
            console.log(drawPile.length - 1);
            drawPile[(drawPile.length - 1)].id = (drawPile.length - 1);
            console.log(drawPile[(drawPile.length - 1)]);
        }