4

I have an array as follows

var sample = [{a:1, b: 1, c:1}, {a:1, b: 1, c:1}, {a:1, b: 1, c:1}];

I then run the following code and try groupsOfItems[0].sample[0].a = 10, groupsOfItems[0].sample[0].a, groupsOfItems[1].sample[0].a and groupsOfItems[2].sample[0].a get changed to 10.

How do I prevent this?

var sample = [{a:1, b: 1, c:1}, {a:1, b: 1, c:1}, {a:1, b: 1, c:1}];


    var groupsOfItems = [];

    for(let i = 0; i < 10; i++) {
        var item = {};
        item.sample = _.clone(sample);
        groupsOfItems.push(item);
    }



  groupsOfItems[0].sample[0].a = 10
  
  console.log(groupsOfItems[0].sample[0].a,groupsOfItems[1].sample[0].a,groupsOfItems[2].sample[0].a);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Jaseem Abbas
  • 5,028
  • 6
  • 48
  • 73
  • 1
    I created a snippet for you. Please do that in the future. Saves a lot of time when testing your code – mplungjan May 06 '16 at 05:41
  • Be wary of cloning objects using libraries (or just in general). If you call a method on a cloned object the method will still be referencing the original object and will modify the original object, not the cloned object. – Kyle Muir May 06 '16 at 05:42

3 Answers3

6

You need to clone the object before assiging its referece to the array's property

Replace

item.sample = sample;

with

item.sample = JSON.parse(JSON.stringify(sample));

Note that this method of cloning will be less efficient when the sample object grows. Try some other methods shown here.

Community
  • 1
  • 1
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
0

as mentioned in this post

for(let i = 0; i < 10; i++) {
        var item = {};
        item.sample = $.extend(true, [], sample);
        groupsOfItems.push(item);
    }
Community
  • 1
  • 1
Nouman Bhatti
  • 1,341
  • 6
  • 28
  • 54
0

I would avoid cloning the object in general. Cloning objects only tends to end in pain further down the track. Here's how I have achieved similar in the past without cloning.

var sample = [{   a: 1,   b: 1,  c: 1}, {  a: 1,  b: 1,  c: 1}, {  a: 1,  b: 1,  c: 1}];
var groupsOfItems = [];

var Item = function(a, b, c) {
  this.a = a;
  this.b = b;
  this.c = c;
}

for (let i = 0; i < 10; i++) {
  var item = {};
  item.sample = _.map(sample, function(item) {
    return new Item(item.a, item.b, item.c)
  });
  groupsOfItems.push(item);
}

groupsOfItems[0].sample[0].a = 10

console.log(groupsOfItems[0].sample[0].a, groupsOfItems[1].sample[0].a, groupsOfItems[2].sample[0].a);
//10 1 1

This way you're assigning them all a container for your modifications and the problem with cloning goes away.

Kyle Muir
  • 3,875
  • 2
  • 22
  • 27