Dercni
Dercni

Reputation: 1224

Storing objects in an array overwrites value

I would like to store an array of objects however it appears that after the object is stored in the array any reference to it changes the original value.

"use strict"

var array = []
var object = {}

object.animal = "Cow"
array.push(object)
object.animal = "Chicken"
array.push(object)

console.log(array) //[ { animal: 'Chicken' }, { animal: 'Chicken' } ]

Edit: I now understand the objects are stored as references in the array. One way to avoid this is to declare an object for each item as suggested below however how can this be achieved in a loop such as the following:

"use strict"

var array = []
var object = {}
var people = ["Mike Brown", "John Brown", "Mary Sue"]
var fname, sname

people.forEach(function(person) {
  [fname, sname] = person.split(" ")
  object.name = person
  object.fname = fname
  object.sname = sname
  array.push(object)
})

Upvotes: 0

Views: 224

Answers (4)

Rainhider
Rainhider

Reputation: 836

I had the same problem, but I was able to fix my issue with the following pseudocode:

var array = [];

function addToArray(){
    var object = {}; //instantiate individual instance here. this is how to make a different value in array for each instance.

    object.animal = 'cow';
    array.push(object);


}

Upvotes: 0

David Jones
David Jones

Reputation: 3352

You are pushing a reference to the object onto the array. What you end up with is two references to the same object. When you change the object's properties you are affecting all references to the object.

If you need to copy an object you can use:

object.animal = "Cow"
array.push(Object.assign({}, object))
object.animal = "Chicken"
array.push(Object.assign({}, object))

console.log(array)

Upvotes: 1

CherryNerd
CherryNerd

Reputation: 1314

That is 100% correct.
This has to do with the way the memory works internally. It works by reference, not by value, like PHP for example does.

So if you'd like to have 2 objects in the array where one contains the string 'cow' and one with 'chicken', you can do 1 of 2:

var array = []
var cow = {animal: 'Cow'};
var chicken = {animal: 'Chicken'};
array.push(cow);
array.push(chicken);
// Reason I'm including this option is because now you can now also do this
cow.farm = 'Kentucky farm';
chicken.eggsPerDay = 1.5;

or the faster way, but not necessarily better

var array = [];
array.push({animal: 'cow'});
array.push({animal: 'chicken'});

Upvotes: 1

ash
ash

Reputation: 532

When you 'push' the object to the array, it's only pushing a reference to the object, not a copy of it.

So in your code above there is only ever 1 object that exists. On your line with "chicken" you are simply overwriting the string "cow".

I would suggest:

var array = []
array.push({animal: "cow"})
array.push({animal: "chicken"})

Upvotes: 3

Related Questions