JavaScript对象属性未替换为新数字

问题描述

所以我已经盯着这个问题有一段时间了,我不知道出了什么问题。我正在尝试创建游戏Yahtzee,并且我有一个可以随机生成5个骰子的函数。当用户希望再次滚动时,也可以重复使用此功能。我传入一个对象数组,每个对象都有一个数字属性,代表用户滚动的内容。我遇到了这个问题,在该循环中,我必须生成一个新的骰子集,而不是替换旧的骰子集。这是我的功能代码

/my-app

现在我可能是错的,但是上面的代码应该可以正常工作,但是我的“ diceSet”在循环前后具有相同的数字,但是我不知道为什么属性没有更改。

这是我的输出

enter image description here

任何帮助将不胜感激

解决方法

值正在变化;只是您正在将值记录到控制台,并且控制台正在显示数组的当前值(在您查看时),而不是在记录数组时立即显示数组中的值。如果要查看值的变化,则将数组转换为字符串,而不是记录数组。

function diceToString(theRoll)
{
  return theRoll.map(roll => roll.number).join(",");
}

function roll(theRoll){
    console.log("before")
    console.log(theRoll)
    console.log(diceToString(theRoll))

    for(let i = 0; i < theRoll.length; i++){
        if(theRoll[i].isHeld == false){
            theRoll[i].number = Math.floor((Math.random() * 6) + 1);
        }
        
        document.getElementById(`die${i + 1}Img`).src = `img/${theRoll[i].number}.png`;
    } 
   
    console.log("After")
    console.log(theRoll)
    console.log(diceToString(theRoll))
    return theRoll;
}

dice = [
  {"isHeld": false,"number": 0},{"isHeld": false,"number": 0}
]

roll(dice);
roll(dice);
roll(dice);
roll(dice);
<img id="die1Img" src="" alt="" />
<img id="die2Img" src="" alt="" />
<img id="die3Img" src="" alt="" />
<img id="die4Img" src="" alt="" />
<img id="die5Img" src="" alt="" />

您还可以运行该代码段并查看输出(以及值的更改),然后将其与浏览器控制台中的日志进行比较以查看区别。

,

这是因为JS中的数组和对象是可变的,这意味着它们被通过引用复制。换句话说,如果您将一个对象(或数组)传递给任何函数(没关系,它是您的函数还是默认函数),实际上您传递引用,而不是副本。

function addOne(obj) {
  obj.value += 1;
}

function addTwo(obj) {
  obj.value += 2;
}

const testObj = {
  value: 0
}

addOne(testObj);
addTwo(testObj);

console.log(testObj)

testObj从未被重新分配,但是value最终等于3。调用函数addTwo时,它已获取了已更新的值(等于1)。实际上,当您将可变实体传递到console.log方法中时,会发生同样的事情-它获取引用,并且您看到对象的“实际”状态,而不是调用时的快照。

此行为还有另一个原因-时间间隔。此答案简要介绍了它们(请参见“ 更多详细信息”块):https://stackoverflow.com/a/30363526/6053654

避免此行为的最简单方法是将数据转换为不可变的类型。字符串非常适合此操作,您可以在将对象登录到控制台之前简单地JSON.stringify将对象登录。