James A
James A

Reputation: 487

Javascript array of objects, objects sharing same member array?

I have an array of objects (this object also contains an array of it's own) I'm not sure why, but when I push some values onto the member array of one instance of the object in the array of objects it also seems to push onto the other member arrays on all other array of objects. I have provided my code below:

var ImageGroup = {
  GroupName:"",
  haz:[]
};

var ImageHandler = {
ImageGroupsArray:[],


image_process: function() {
//Calling the function here...

//Pushing the objects
this.ImageGroupsArray.push(Object.create(ImageGroup));
this.ImageGroupsArray.push(Object.create(ImageGroup));

//Assigning some values
this.ImageGroupsArray[0].haz.push("Dog");
this.ImageGroupsArray[1].haz.push("Cat");

//Should output array with only 'Dog' in it
console.log(this.ImageGroupsArray[0].haz);

//Should output array with only 'Cat' in it
console.log(this.ImageGroupsArray[1].haz);

//Instead, both of these output ["Dog","Cat"]
//this.ImageGroupsArray[1].haz and this.ImageGroupsArray[0].haz point to same 'haz' array??
}
}

This doesn't happen when I try to set the GroupName the same way. What am I doing wrong? Thanks for any help in advance!

Upvotes: 1

Views: 67

Answers (3)

bowheart
bowheart

Reputation: 4676

This code:

var ImageGroup = {
  GroupName:"",
  haz:[]
};

creates a single object in memory. This code:

this.ImageGroupsArray.push(Object.create(ImageGroup));
this.ImageGroupsArray.push(Object.create(ImageGroup));

creates two new objects (pushing each onto the ImageGroupsArray). Both of these objects have the same ImageGroup object as their prototype. Just knowing how prototypes work will help you a lot on this one. But basically, this code:

this.ImageGroupsArray[0].haz.push("Dog");
this.ImageGroupsArray[1].haz.push("Cat");

looks for the haz property on each of those Object.create()ed objects. When it can't find it, it looks up the prototype chain and finds it on the parent object (which is the same object in both cases). Any modifications made to this one object will, of course, show up in all places where this object is referenced (so in both the objects you pushed to ImageGroupsArray).

The correct approach is to declare ImageGroup as a function that defines its properties:

var ImageGroup = function() {
    this.GroupName = '';
    this.haz = [];
}

then use the new keyword, instead of Object.create():

this.ImageGroupsArray.push(new ImageGroup());
this.ImageGroupsArray.push(new ImageGroup());

Cheeers.

Upvotes: 1

Pawan Nogariya
Pawan Nogariya

Reputation: 8980

You are pushing same object ImageGroup in ImageGroupArray and so it is actually making effect in the same object which is defined globally.

Try this instead

function getImageGroup()
{
   var imageGroup = new Object();
   imageGroup.GroupName = "";
   imageGroup.haz = [];

   return imageGroup; 
}

this.ImageGroupsArray.push(getImageGroup());
this.ImageGroupsArray.push(getImageGroup());

Working Fiddle

Upvotes: 1

Guidhouse
Guidhouse

Reputation: 1426

It seems you are referencing the same ImageGroup object twice. The 'groupName' property gets overwritten, but the array can grow endlessly :-)

Try:

var ImageGroup1 = {  GroupName:"foo",  haz:[]};
var ImageGroup2 = {  GroupName:"bar",  haz:[]};

So you get two different objects in stead of two references to the same object.

Upvotes: 0

Related Questions