0

I create multiple objects and push them to the array objArr:

var objArr = [];
var obj = {};
var height = [9,8,7,3,6,5,2,4];

for (var i = 0; i < 8; i++) {
debugger;
  var mountainH = height[i];

  obj.h = mountainH;
  obj.index = i;

  objArr.push(obj);
}

for (var i = 0; i < objArr.length; i++) {

  alert(objArr[i].h);
}

But as you can see, each object has the same values. Why?

enter image description here

Black
  • 18,150
  • 39
  • 158
  • 271
  • 1
    Because you aren't creating a bunch of objects, just modifying the same one over and over. – takendarkk Feb 12 '18 at 22:09
  • Because you're reusing the same `obj` on each push. So each time you mutate it by doing `obj.h = ...` it will change all the previously pushed ones too. Try creating the object inside the loop instead. – CRice Feb 12 '18 at 22:09
  • The value updates are by reference. – nurdyguy Feb 12 '18 at 22:10
  • You shouldn't use a for loop with a static number like that. If you array changes, you have to modify it. use `height.length` to avoid nonsensical issues – Sterling Archer Feb 12 '18 at 22:15
  • Possible duplicate of [Array.push() makes all elements the same when pushing an object](https://stackoverflow.com/questions/10932584/array-push-makes-all-elements-the-same-when-pushing-an-object) – Heretic Monkey Feb 12 '18 at 22:21

3 Answers3

4
  • Put the initialization of obj within your for-loop.

You were re-assigning new values to a global variable obj.

var objArr = [];

var height = [9,8,7,3,6,5,2,4];

for (var i = 0; i < 8; i++) {
debugger;
  var obj = {};
  var mountainH = height[i];

  obj.h = mountainH;
  obj.index = i;

  objArr.push(obj);
}

for (var i = 0; i < objArr.length; i++) {

  console.log(objArr[i].h);
}
Ele
  • 33,468
  • 7
  • 37
  • 75
3

Because the scope of obj in your code is global and it should rather be contained in the for loop.

If you will not declare it inside the loop then the value will get overwritten of the same obj on each iteration instead of a new memory allocation.

var objArr = [];
var height = [9, 8, 7, 3, 6, 5, 2, 4];

for (var i = 0; i < 8; i++) {
  debugger;
  var mountainH = height[i];
  var obj = {};

  obj.h = mountainH;
  obj.index = i;

  objArr.push(obj);
}
console.log(obj);
void
  • 36,090
  • 8
  • 62
  • 107
1

As noted, you need to initialize a new object in each iteration of the loop, otherwise all your array members simply share the same object reference.

Additionally, your code can be greatly reduced by building the array using .map(), and fully using the object literal initializer to declare the properties.

var height = [9,8,7,3,6,5,2,4];
var objArr = height.map((n, i) => ({h: n, index: i}));

console.log(objArr);

This is shorter and clearer. For every number in height, it creates a new object and adds it to a new array, which is returned from .map().


It can be even a little shorter with the newer features for object literals.

var height = [9,8,7,3,6,5,2,4];
var objArr = height.map((h, index) => ({h, index}));

console.log(objArr);