0

I am assigning random values between 1-50 to object elements, I have 5 objects, I don't know why but all the objects are getting the same random values...

here is my code :

var SmileyRed = {
   radius: 15,
   xspeed: 0,
   yspeed: 0,
   xpos:350,  // x-position of smiley
   ypos: 65  // y-position of smiley
};

var SmileyReds = new Array();

 for (var i=0; i<5; i++){
 SmileyReds[i] = SmileyRed;
 SmileyReds[i].xspeed = Math.floor((Math.random()*50)+1);
 SmileyReds[i].yspeed = Math.floor((Math.random()*50)+1);
 }

SmileyReds[0].xspeed and SmileyReds[3].xspeed have the same values but shouldn't they be different?

Anarkie
  • 657
  • 3
  • 19
  • 46
  • Your array contains 5 references to the same object. There is only one SmileyRed. – bfavaretto Nov 10 '13 at 20:10
  • @bfavaretto I just figured it out the original SmileyRed shows also the same random values, I thought I was making a copy of SmileyRed each time... how can I make them different independent objects? – Anarkie Nov 10 '13 at 20:13

2 Answers2

3

The problem is that the indexes from 0 to 4 contains references to the same object SmileyRed. You should create a new object for each iteration if you want to seperate them.

So you are actually changing the same object in each iteration. Thereby you will always use the last random numbers (from the last object).

By calling a function which returns an object, you'll get a new object for every iteration. Like below.

var SmileyRed = function() {
    return {
       radius: 15,
       xspeed: 0,
       yspeed: 0,
       xpos:350,  // x-position of smiley
       ypos: 65  // y-position of smiley
    }
};

var SmileyReds = new Array();

 for (var i=0; i<5; i++){
     SmileyReds[i] = SmileyRed();
     SmileyReds[i].xspeed = Math.floor((Math.random()*50)+1);
     SmileyReds[i].yspeed = Math.floor((Math.random()*50)+1);
 }

JSfiddle

Peter Rasmussen
  • 16,474
  • 7
  • 46
  • 63
3

The problem is that when you make an object equal to another object, the new object is a refrence of the original, not a copy.

What is happening is you are creating 5 referencs to the original SmileyRed. Essentially when you change one, you change all. So only value being applied in your loop is from last pass of the loop, the previous 4 passes are overwritten.

You could change to:

var SmileyReds = new Array();

 for (var i=0; i<5; i++){
/* new object each pass*/
 SmileyReds[i] =  {
   radius: 15,
   xspeed: 0,
   yspeed: 0,
   xpos:350,  // x-position of smiley
   ypos: 65  // y-position of smiley
};
 SmileyReds[i].xspeed = Math.floor((Math.random()*50)+1);
 SmileyReds[i].yspeed = Math.floor((Math.random()*50)+1);
 }

Another way would be:

var SmileyRed = function(){
    return{
       radius: 15,
       xspeed: 0,
       yspeed: 0,
       xpos:350,  // x-position of smiley
       ypos: 65  // y-position of smiley
    };
}

 for (var i=0; i<5; i++){
    /* new object each pass*/
     SmileyReds[i] =  SmileyRed();/* note () this time*/
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • I see this is creating 5 objects, isn't there a way to copy SmileyRed and then work on the elements? I think copying this object would be easier. – Anarkie Nov 10 '13 at 20:17
  • @Anarkie there's no built-in object copy mechanism in JavaScript. You can write a function to do it, but it's a somewhat complicated problem in general. – Pointy Nov 10 '13 at 20:18
  • Maybe by using `jQuery.extend` http://api.jquery.com/jQuery.extend/ http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object – XCS Nov 10 '13 at 20:18
  • yes...see new update...I know you need to create more at various intervals in your game – charlietfl Nov 10 '13 at 20:20