Raggaer
Raggaer

Reputation: 3318

JavaScript array cloning

I have this way to make an array

var playerList = [];

exports.player = function(socket, name)
{
    this.id = socket.id;
    this.name = name;
    this.x = 20;
    this.y = 40;

    return this
}

exports.addPlayer = function(data)
{
    playerList.push(data)
}

And I'm adding items to playerList array like this

var client = new player(socket, data);
exports.addPlayer(client);

But I also got a function that makes the following

exports.getSafeList = function(id)
{
    var player_array = playerList.slice();

    for(var i = 0; i < player_array.length; i++)
    {
        if(player_array[i].id != id)
        {
            player_array[i].id = 'unknown';
        }
    }

    return player_array;
}

And now I do the following

exports.getPlayerList = function()
{
    return playerList;
}

console.log(players.getPlayerList())
console.log(players.getSafeList(id))

So far the code is working fine but when I log the 2 functions it seems that getPlayerList variable merges with player_list one, this is the output

When theres just ONE player on the array

[ { id: 'tjvh8XdMtX-o6QYDAAAB', name: 'Raggaer', x: 20, y: 40 } ]

[ { id: 'tjvh8XdMtX-o6QYDAAAB', name: 'Raggaer', x: 20, y: 40 } ]

But when there are more:

[ { id: 'unknown', name: 'Raggaer', x: 20, y: 40 },
  { id: '2-K5At07wLV4BDiAAAAC', name: 'Alvaro', x: 20, y: 40 } ]

[ { id: 'unknown', name: 'Alvaro', x: 20, y: 40 },
  { id: '2-K5At07wLV4BDiAAAAC', name: 'Alvaro', x: 20, y: 40 } ]

As you can see on both arrays id appears as "unknown" when it shouldn't, since I'm not modyfing the playerList array...

Upvotes: 2

Views: 69

Answers (1)

Troy Gizzi
Troy Gizzi

Reputation: 2520

The problem is that while Array.prototype.slice() will create a separate copy of the original array, its items will still be references to the same object instances. So modifying an item in one array ends up modifying the corresponding item in the cloned array.

If your items are simple data objects (no functions), this workaround might do the trick for you:

// instead of "var player_array = playerList.slice();"
var player_array = JSON.parse(JSON.stringify(playerList));

Upvotes: 1

Related Questions