I have an object in an array, and the array is iterated through, running a method on each of the elements (which are all the same class). In the method it tries to get the element’s index in the array:
const index = game.players.indexOf(this)
This obviously should return the index, since no modifications to the element have been made (its one of the first lines in the method), however it returns -1
So I put in this line:
console.log(game.players[0], this, game.players[0] == this)
It gave me the two identical-looking objects, and false. I spent a couple minutes double and triple checking both objects for differences, eventually just searched up a text difference checker and…the two objects are identical?? (i included the whole objects incase anyone wanted to see them)
What???? is this some weird behind the scenes memory thing I dont know about?? I tried both === and ==, both returned false.
Here is all the relevant code:
//iterating through the loop
for (let i in this.players) {
let actionChance = 1
while (Math.random() <= actionChance) {
// run newAction() on each item
result.push(this.players[i].newAction(this.players.length))
actionChance *= 0.6
}
}
newAction(players, round) {
//getting the parent object which is iterating through the array and running this method
const data = require('./data.json')
//the game is saved to data.json as a string, and then i have a static method to convert the parsed object to an instance of the game class
let game = Game.toGame(JSON.parse(data[this.gameID]))
//get the index
const index = game.players.indexOf(this)
>Solution :
This issue is likely due to the behavior of indexOf when used with objects in JavaScript, combined with how you’re handling object deserialization from JSON.
When you use indexOf, it checks for the object’s reference in memory, not the object’s value or properties. Since objects in JavaScript are reference types, two objects with identical properties do not necessarily equal each other (i.e., {} is not === to {}) because they occupy different locations in memory.
In your case, game.players.indexOf(this) returns -1 because the this reference inside newAction does not strictly equal (===) any object in game.players. This discrepancy arises from how you recreate your game object:
let game = Game.toGame(JSON.parse(data[this.gameID]))
To work around this, you need a way to identify players that does not rely on object references. A common approach is to use a unique identifier (e.g., an ID property) for each player. You could then find the index based on this identifier instead of using indexOf directly on the object reference.
const index = game.players.findIndex(player => player.id === this.id);
This solution assumes you modify your Game.toGame method and player objects to include and handle unique IDs correctly. By comparing a property value (which is not affected by object reference issues), you can accurately find the index of this player in the game.players array