6

So I was testing this little peace of code:

<script>
  var newData = {}, graphs = []
  for(var j=0; j<2; j++){
    newData["name"] = 'value '+ j
    console.log(newData["name"]);
    graphs.push(newData);
    console.log(graphs);
  }
</script>

I've got the following output in the webconsole:

value 0 
Array [ Object ] 
value 1 
Array [ Object, Object ]

All Objects in the Arrays have the exact same Values:

name:"value 1"

I am really struggling with this because I don't change any values and the name is still changed in the same loop.

Thanks for your answers in advance!

GuyWithCookies
  • 630
  • 2
  • 8
  • 21
  • 1
    You are changing a property of one and the same object. You're never creating a second object anywhere, there's only one object which gets referred to multiple times. – deceze Mar 11 '16 at 13:00
  • I'd just add, for clarity, that before the 2nd iteration of the loop occurs, the array is [{name:"value 0"}]. In the 2nd iteration, it becomes [{name:"value 1"},{name:"value 1"}]. – snoski Feb 14 '20 at 14:06

3 Answers3

12

Putting an object into an array in javascript means you're putting a reference to that object in the array rather than the value of that object. In your example, you create a single object, newData and you change the name property on that object in your loop. That means that at the end of the loop you're left with a newData object with {'name': 'value 2'}

When you then take a look at graphs[0], it will tell you that it contains a reference to newData which looks like {'name': 'value 2'}. The same holds for graphs[1]

you can solve this by making a new object each time in your array as such:

graphs = []
for(var j=0; j<2; j++){
  var newData = {}
  newData["name"] = 'value '+ j
  console.log(newData["name"]);
  graphs.push(newData);
  console.log(graphs);
}
Matthijs Brouns
  • 2,299
  • 1
  • 27
  • 37
  • Mrmrmrm.... The *value* of a variable holding an object *is* a reference to said object. You *are* putting a *value* into the array, it just so happens that that value is an indirection... /pedantic :o) – deceze Mar 11 '16 at 13:14
  • you're absolutely correct, i'll update my answer to reflect that – Matthijs Brouns Mar 11 '16 at 13:15
  • Perhaps it should be noted that any changes to `newData["name"]` **after** the for loop (i.e. `newData["name"] = 'object name';`) would change the last item and only the last item in the `graphs` array unless of course newData was reinitialized again beforehand. – snoski Feb 14 '20 at 14:34
1

Edit : You have to reinitialize the newData in the loop. Because, the object reference of newData is same and it overwrites the old value with new value everytime and hence only latest value can be seen.

Try,

<script>
    var graphs = [];
    for(var j=0; j<2; j++){
      var newData = {};
      newData["name"] = 'value '+ j
      console.log(newData["name"]);
      graphs.push(newData);
      console.log(graphs);
   }
 </script>
Mahesh Hegde
  • 184
  • 1
  • 4
0

Thanks to deceze for his answer! I forgot that Js just calls by reference. This code is working:

var graphs = []
  for(var j=0; j<2; j++){ 
    newData = {}
    newData["name"] = 'value '+ j
    console.log(newData["name"]);
    graphs.push(newData);
    console.log(graphs);
  }
GuyWithCookies
  • 630
  • 2
  • 8
  • 21