问题描述
所以我已经盯着这个问题有一段时间了,我不知道出了什么问题。我正在尝试创建游戏Yahtzee,并且我有一个可以随机生成5个骰子的函数。当用户希望再次滚动时,也可以重复使用此功能。我传入一个对象数组,每个对象都有一个数字属性,代表用户滚动的内容。我遇到了这个问题,在该循环中,我必须生成一个新的骰子集,而不是替换旧的骰子集。这是我的功能代码
/my-app
现在我可能是错的,但是上面的代码应该可以正常工作,但是我的“ diceSet”在循环前后具有相同的数字,但是我不知道为什么属性没有更改。
这是我的输出
任何帮助将不胜感激
解决方法
值正在变化;只是您正在将值记录到控制台,并且控制台正在显示数组的当前值(在您查看时),而不是在记录数组时立即显示数组中的值。如果要查看值的变化,则将数组转换为字符串,而不是记录数组。
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
将对象登录。