Object.values()无法更新G.playerStatsDifference变量问题排查
Object.values()循环赋值失效问题分析与解决
问题场景
定义了数组对象类型变量G.playerStatsDifference,用于计算频繁变化的G.playerStats的差值:
playerStatsDifference: [{ carpenter: 0, wood: 0, gunman: 0, gunpowder: 0, merchant: 0, gold: 0, fleet: 0, flagship: 0, }, { carpenter: 0, wood: 0, gunman: 0, gunpowder: 0, merchant: 0, gold: 0, fleet: 0, flagship: 0, }]
编写的差值计算函数中,使用Object.values()循环赋值时,G.playerStatsDifference未更新,但控制台计算结果正确;直接通过属性名赋值却有效:
// 无效的循环赋值代码 const oldPlayerStats = JSON.parse(JSON.stringify(G.playerStats)); statsDifference(G, oldPlayerStats); for (let p = 0; p < 2; p++) { for (let s = 0; s < 8; s++) { Object.values(G.playerStatsDifference[p])[s] = Object.values(G.playerStats[p])[s] - Object.values(oldPlayerStats[p])[s]; } } // 有效的直接属性赋值 G.playerStatsDifference[0].wood = Object.values(G.playerStats[0])[1] - Object.values(oldPlayerStats[0])[1];
问题原因
Object.values()返回的是原对象属性值的浅拷贝数组。因为你的属性值都是数字(值类型),数组里存储的是这些数字的副本而非原对象属性的引用。修改这个数组里的元素时,只是修改了副本的值,根本不会同步到原对象的属性上,所以G.playerStatsDifference没有被更新。而直接通过属性名赋值是直接操作原对象的属性,自然能生效。
循环实现赋值的正确方法
方法1:通过Object.keys()遍历属性名赋值
利用Object.keys()获取对象的属性名数组,再通过属性名直接操作原对象的属性:
const oldPlayerStats = JSON.parse(JSON.stringify(G.playerStats)); statsDifference(G, oldPlayerStats); for (let p = 0; p < 2; p++) { const statKeys = Object.keys(G.playerStatsDifference[p]); for (let s = 0; s < statKeys.length; s++) { const key = statKeys[s]; G.playerStatsDifference[p][key] = G.playerStats[p][key] - oldPlayerStats[p][key]; } }
方法2:用forEach简化遍历逻辑
更简洁的写法,通过嵌套forEach遍历玩家和属性:
const oldPlayerStats = JSON.parse(JSON.stringify(G.playerStats)); statsDifference(G, oldPlayerStats); G.playerStatsDifference.forEach((diffStats, playerIndex) => { Object.keys(diffStats).forEach(statKey => { diffStats[statKey] = G.playerStats[playerIndex][statKey] - oldPlayerStats[playerIndex][statKey]; }); });
内容的提问来源于stack exchange,提问作者evilgenious448
相关产品推荐
相关产品推荐

