4

I am trying to do the following:

var element = {};
element.attrA = 'A';
element.attrB = 1;
element.autoAdvance = function(){
   var that = this;
   setInterval(function(){
     that.attrB++;
   },100);
}
element.instance = function(){
   var clone = $.extend(true, {}, this);
   return clone;
}

Now I can do the following just fine:

var e1 = element.instance();
var e2 = element.instance();
e1.attrA = 'not e2s business';
e2.attrA = 'not e1s attrA';

The trouble starts when I try to use autoAdvance:

e1.autoAdvance();

will start the autoAdvance for all cloned 'instances' of element. I am sure this is probably rather trivial but I just don't know how to refer to the parent object inside my autoAdvance-function in a way that it gets properly cloned and only affects the instance. Thanks!

EDIT:

This is the actual code I am using:

var player = {}; 
player.sprites = {};
player.sprites.back = ['img/playerback_01.png','img/playerback_02.png','img/playerback_03.png'];
player.sprites.head = ['img/playerhead_01.png','img/playerhead_02.png','img/playerhead_03.png'];
player.back = new Image();
player.back.src = player.sprites.back[0];
player.head = new Image();
player.head.src = player.sprites.head[0];
player.loop = function(){
    var that = this;
    var loop = setInterval(function(){
            //remove the [0] state from the sprite array and add it at [2]
        var state = that.sprites.head.shift();
        that.sprites.head.push(state);
        state = that.sprites.back.shift();
        that.sprites.back.push(state);
        that.back.src = that.sprites.back[0];
        that.head.src = that.sprites.head[0];
        }, 100);
}
player.x = 0;
player.y = 0;
player.instance = function(){
   var clone = $.extend(true, {}, this);
   return clone;
}

I generate two players:

var player1 = player.instance();
var player2 = player.instance();

But what is happening is that when I use:

player1.loop();

The animation for player2 will start to play as well.

m90
  • 11,434
  • 13
  • 62
  • 112
  • Looks fine to me. Proof: http://jsfiddle.net/Q45ft/ What `this` refers to depends on how the function is called. As you call it as `e1.autoAdvance()`, `this` will refer to `e1` inside `autoAdvance` and won't affect any other objects. – Felix Kling Feb 14 '12 at 12:24
  • Hmm, my 'actual' code is a little more complex, but I'll add it to the question. – m90 Feb 14 '12 at 12:27
  • 1
    I assume that `$.extend` does not know how to clone the `back` and `head` objects (because they are `Image`s, extend only works properly with arrays and objects ([source](https://github.com/jquery/jquery/blob/master/src/core.js#L303))). I would just use a constructor function and create instances with that one. – Felix Kling Feb 14 '12 at 12:35
  • Ok, this: http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object lead me to thinking it would deep clone the object. Any tip on deep cloning? – m90 Feb 14 '12 at 12:38
  • I was wrong, see my edited comment. – Felix Kling Feb 14 '12 at 12:38
  • Using a constructor works just fine! Thanks! – m90 Feb 14 '12 at 13:00

1 Answers1

0

I suggest you start using "class" in JavaScript. They are more or less a function.

function Player(){
this.sprites={};
......
}
Player.prototype.loop=function(){
....
}
var player1=new Player();
var player2=new Player();
player1.loop();
player2.loop();// this should work better

It doesn't really answer your question but it's an alternative way to write code in a cleaner and better way.

Bogdan.Nourescu
  • 905
  • 6
  • 17
  • Just saw your answer today as Felix already suggested this in the comments to my question. That's exactly what I ended up with. Thanks for the hint. – m90 Feb 20 '12 at 10:24