0

I am trying to get a create a variable oldPlayerStats to get the current value of G.playerStats, so that later when G.playerStats gets updated, I can subtract the oldPlayerStats from the new value of G.playerStats to get the difference.

However for some reason, oldPlayerStats updates to always match G.playerStats.

Relevant code below:

const oldPlayerStats = G.playerStats;
console.log(oldPlayerStats[0].wood); //Is 10 as it should be

//This function affects the value of `G.playerStats`. It does not do anything to oldPlayerStats
cardFunction.function(G, ctx, ctx.currentPlayer, G.opponent, G.attackMultiplier);
    
console.log(oldPlayerStats[0].wood); //Should be 10, but instead updates to match the new value of `G.playerStats`
evilgenious448
  • 518
  • 2
  • 11

4 Answers4

3

Right now oldPlayerStats is just referencing the original object in memory, and that is why it is changing.

One option is to clone the object using structured clone to create a deep clone.

https://developer.mozilla.org/en-US/docs/Web/API/structuredClone

const oldPlayerStats = structuredClone(G.playerState)
ramseylove
  • 43
  • 4
  • Unfortunately this gives me the following error: `Uncaught DOMException: Failed to execute 'structuredClone' on 'Window': [object Array] could not be cloned.` Also, you have written "State" instead of "Stats" in your example, however I have used the correct variable names. – evilgenious448 Nov 20 '22 at 14:08
  • fixed the typo but It would be helpful to know the structure of the object, and if playerstats can be an empty array. You will more than likely need to use optional chaining if the playerStats array can be empty. – ramseylove Nov 21 '22 at 16:23
1

In Javascript, when you assign a variable to another variable, you are doing so by reference. So instead of saying "i want oldPlayerStats to equal the value of G.playerStats", it's saying oldPlayerStats points to the memory address where G.playerStats is stored. Therefore when you update one, it will update the other.

you can use slice to copy the values from an array into a new array.

ie

oldPlayerStats = G.playerStats.slice()
  • Unfortunately this is giving me the error `Cannot convert undefined or null to object` – evilgenious448 Nov 20 '22 at 14:06
  • @evilgenious448 that means you've got `undefined` or `null` instead of an object reference. – Pointy Nov 20 '22 at 14:26
  • @Pointy you are right, I had an error in my code elsewhere. Having fixed that error, this time I do not get an error, but the value still changes despite me using the `.slice()` – evilgenious448 Nov 20 '22 at 14:30
0

I`m far from being an expert in JS, but in most languages, assigning complex data structure to another variable, uses reference - the data is not copied, but the new variable, points to the same place in memory. Therefore, if you change some of the original datastructure's elements, but not the adress in memory, the new variable will still show the updated value of the original one. There are several methods to avoid it. In case of JavaScript, this should help: https://www.freecodecamp.org/news/how-to-clone-an-array-in-javascript-1d3183468f6a/

Ni3dzwi3dz
  • 177
  • 8
0

Although the provided answers all made sense and there was plenty of other documentation supporting those answers as possible solutions, neither of them worked.

What did end up working for me was:

const oldPlayerStats = JSON.parse(JSON.stringify(G.playerStats));

This solution came from the following question I found: Uncaught DOMException: Failed to execute 'postMessage' on 'Window': An object could not be cloned

evilgenious448
  • 518
  • 2
  • 11