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>

2
  • 1
    I created a snippet for you. Please do that in the future. Saves a lot of time when testing your code Commented May 6, 2016 at 5: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. Commented May 6, 2016 at 5:42

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I did try with _.clone. Didn't help
@JaseemAbbas did you tried the method I have shared
@JaseemAbbas _.clone() is a shallow copy. the JSON method does a deep clone.
_.cloneDeep() saved my day. Cheers!
0

as mentioned in this post

for(let i = 0; i < 10; i++) {
        var item = {};
        item.sample = $.extend(true, [], sample);
        groupsOfItems.push(item);
    }

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.