akcoban
akcoban

Reputation: 973

JavaScript can't set current situation of modified object to array in for loop

When I run this code, all object of the array are the same.

var obj = {
    	a: { b: 0 }
    }

    var arr = [];

    for(i = 0; i < 10; i++) {
    arr.push(obj);
    obj.a.b += 5;
    }

    for(i = 0; i < arr.length; i++) {
    document.writeln(arr[i].a.b);
    }

How can I send current values of the object to the array? Like:

[
  {"a": b: 5 },
  {"a": b: 10 },
  {"a": b: 15 },
...
]

jsfiddle

enter image description here


After Answered

I created a benchmark test for Object.assign vs JSON.stringify for the deep clone.

http://jsben.ch/64Cxe

Upvotes: 2

Views: 78

Answers (3)

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92367

Chrome console don't show full object for console.log(obj); but only { a: {...} } - and when you click on "triangle" to show object content chrome console use actual object value.

StackOverflow snipped show full object content immediately on each iteration - but chrome only keep reference to object and look on him deeper only when user click on "triangle" in console.

You should make nested(deep) copy (popular way is for example JSON.parse(JSON.stringify(obj)) but you can find better ways on StackOverflow) of object at current loop iteration and give that deep copy to console.log(copyObj); . For example:

var obj = {
  a: {
    b: 0
  }
}

for (i = 0; i < 10; i++) {
  obj.a.b += 5;
  console.log('log obj.a.b = ' + obj.a.b);
  console.log( JSON.parse(JSON.stringify(obj)) );
}

After question update

The arr.push(obj) push only reference to the same object obj to array, use below code to add separate copy of obj (reference to copy to be precise) as new array element:

arr.push( JSON.parse(JSON.stringify(obj)) )

Upvotes: 1

naortor
naortor

Reputation: 2089

obj is a reference to an object, so what you are really doing is pushing the same reference to an object over and over again.

You end up with an array of the same reference to an object. if you want an array of different objects, you need to make a copy of the object before pushing it, you can accomplish it by

arr.push({...obj})

or

arr.push(Object.assign({},obj})

Upvotes: 2

Remco
Remco

Reputation: 58

This has to do with value versus reference.

Stackoverflow turns the value of the object into a string before logging. When you then change the value of the object the string doesn't change.

The chrome logs do it a bit different, they log the actual value of the object by looking at a certain point in memory, when you then edit that object the log will also update because it still points to that part of the memory.

If you'd like to also turn it into a string you could use JSON.stringify(obj);

Upvotes: 0

Related Questions