N
N
Nikolay Marinkin2015-05-05 10:20:13
JavaScript
Nikolay Marinkin, 2015-05-05 10:20:13

Why does the object change after the function call?

There is this simplified code:

var Game = function (players) {
  this.game = {
    players: []
  };

  console.log(this.getStateWithMe(players[0]).players); //тут все нормально
  console.log(this.getStateWithMe(players[1]).players); //а тут this.game уже изменен
}

Game.prototype = {
  getStateWithMe: function (player) {
    //функция должна возвращать модифицированную копию this.game
    var g = {};
    for (prop in this.game) if (this.game.hasOwnProperty(prop)) {
      g[prop] = this.game[prop];
    }

    g.players.push(player);

    return g;
  }
}

new Game(['a', 'b']);

I'm trying to implement a function to get a child object, depending on a parameter. But the problem is that the prototype function getStateWithMe() modifies the object itself.
As I understand it, this is due to the fact that var creates a reference to an object, and not a copy of it.
How can I fix this by leaving the function in the prototype?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
K
Konstantin Kitmanov, 2015-05-05
@NicoBurno

No, that's because this.game.players is an array, and thus a reference type. That is, g.players and this.game.players refer to the same object.
You need a function that does a deep clone. The most concise way that I know is JSON.parse(JSON.stringify(this.game))if you don’t have tricky data like dates and regexps there, then everything should be fine.

V
Vitaly, 2015-05-05
@xytop

var g = jQuery.extend(new Game([]), this.game);

K
keslo, 2015-05-05
@keslo

var Game = function (players) {
  this.game = {
    players: []
  };

  console.log(this.getStateWithMe(players[0]).players); // тут все нормально
  console.log(this.getStateWithMe(players[1]).players); // и тут вроде тоже
}

Game.prototype = {
  getStateWithMe: function (player) {

    var g = {};
    g.players = this.game.players.slice(0); // копируем массив-значение из this.game.players
    g.players.push(player);

    return g;
  }
}

new Game(['a', 'b']);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question