2

I've made this jsfiddle and I can't explain why the following doesn't result in an array of 5 objects all with different id properties:

var arr = ["1", "2", "3", "4", "5"];
var clone = {"id": "0", "name":"Matthew"};
var arrObj = [];

var idArr = [];

while((a=arr.pop()) != null){ 
    clone.id = a;
    console.log(clone);
    arrObj.push(clone);
}

console.log(arrObj);

What I end up getting is the following in my console:

Object {id: "5", name: "Matthew"} (index):28
Object {id: "4", name: "Matthew"} (index):28
Object {id: "3", name: "Matthew"} (index):28
Object {id: "2", name: "Matthew"} (index):28
Object {id: "1", name: "Matthew"} (index):28

[Object, Object, Object, Object, Object]

When I open each of the 5 cloned objects they all have an "id" value of "1"

Why is this?

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
ganicus
  • 321
  • 5
  • 12
  • 1
    Objects are passed by reference, You're referring to the same object, again and again. You need to clone it. http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object – elclanrs Mar 08 '14 at 01:11
  • possible duplicate of [Add values to an array](http://stackoverflow.com/questions/18267367/add-values-to-an-array) – Felix Kling Mar 08 '14 at 01:29
  • Good thread you referenced! I would have never found my answer though because that article has such a vague title and tags. Besides, this question address the caveats of referencing objects outside a loop and assigning values to them in the way described above. Brings a different perspective to a similar question, but not exactly a duplicate. – ganicus Mar 08 '14 at 02:30

3 Answers3

4

clone is an object. In javascript, Objects are passed by reference, so you are not passing a different object in each index.

Here is something that will work

while((a=arr.pop()) != null){
    var clone = {"id": a, "name":"Matthew"};
    clone.id = a;
    arrObj.push(clone);
}

console.log(arrObj); 

Result:

Array [
    Object {id: "5", name: "Matthew"}
    Object {id: "4", name: "Matthew"}
    Object {id: "3", name: "Matthew"}
    Object {id: "2", name: "Matthew"}
    Object {id: "1", name: "Matthew"}
]
Ibu
  • 42,752
  • 13
  • 76
  • 103
2

Objects in JS are assigned by reference. You need to duplicate it, with something like jQuery.extend.

var arr = ["1", "2", "3", "4", "5"];
var clone = {"id": "0", "name":"Matthew"};
var arrObj = [];

var idArr = [];

while((a=arr.pop()) != null){ 
    clone = $.extend({}, clone);
    clone.id = a;
    console.log(clone);
    arrObj.push(clone);
}

console.log(arrObj);
sabof
  • 8,062
  • 4
  • 28
  • 52
  • 1
    @elclanrs You can re-implement `$.extend`, if it makes you warm and fuzzy. – sabof Mar 08 '14 at 01:13
  • That was blazingly fast, thank you! I would like to see a non-jquery answer as well, but you definitely deserve the check mark. I'll have to read up more about Object references in JS. – ganicus Mar 08 '14 at 01:15
  • @sabof how would you re-implement? – ganicus Mar 08 '14 at 01:15
  • @ganicus An implementation shouldn't be hard to find. Just google for "clone object javascript". – sabof Mar 08 '14 at 01:17
1

If your clone does not contain any function you can do this

while((a=arr.pop()) != null){
    clone = JSON.parse(JSON.stringify(clone));
    clone.id = a;
    console.log(clone);
    arrObj.push(clone);
}
axelduch
  • 10,769
  • 2
  • 31
  • 50
  • JSON is a subset of JavaScript. While this works in this example, a lot of JavaScript values would be defaulted to `null` – sabof Mar 08 '14 at 01:26