0

The array changes its value even though it was pushed earlier

var original = 
[{
    a: 1,
    data: 
        { b: 'before' }
},
{
    a: 2,       
    data: 
        { b: 'before' }
}];

var arr1 = [];
var arr2 = [];


for(i=0; i<original.length; i++) {
    let value = original[i];

    //pushed earlier
    arr1.push(value);

    let newvalue = original[i];
    if (newvalue.data.b == "before") {
        newvalue.data.b = "after";
        arr2.push(newvalue);
    }
}

console.log("ARRAY 1 ");
console.log(arr1);
console.log("ARRAY 2 ");
console.log(arr2);

produces

ARRAY 1 
[ { a: 1, data: { b: 'after' } }, { a: 2, data: { b: 'after' } } ]
ARRAY 2
[ { a: 1, data: { b: 'after' } }, { a: 2, data: { b: 'after' } } ]

I am guessing this has something to do with how JS changes the value since it is being reference by the original array itself.

Whats the optimal solution in such cases where you have to retain the original array while use it to modify and create another array?

Asghar Musani
  • 568
  • 4
  • 20
  • https://stackoverflow.com/questions/67546996/a-json-file-created-with-nodejs-holds-the-wrong-data/67547050#67547050 does this solve your question? – Hive7 May 15 '21 at 13:41
  • 1
    Or here: https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript – Hive7 May 15 '21 at 13:42

2 Answers2

1

Arrays and Objects in javascript are pass by reference by default.

If you want to avoid this behaviour, you could use Object.assign but that fails for deep copy of objects so you'll have to use JSON.parse(JSON.stringify(obj)) here,

let newvalue = JSON.parse(JSON.stringify(original[i]));

var original = [{
    a: 1,
    data: {
      b: 'before'
    }
  },
  {
    a: 2,
    data: {
      b: 'before'
    }
  }
];

var arr1 = [];
var arr2 = [];


for (i = 0; i < original.length; i++) {
  let value = JSON.parse(JSON.stringify(original[i]));

  //pushed earlier
  arr1.push(value);

  let newvalue = JSON.parse(JSON.stringify(original[i]));
  if (newvalue.data.b == "before") {
    newvalue.data.b = "after";
    arr2.push(newvalue);
  }
}

console.log("ARRAY 1 ");
console.log(arr1);
console.log("ARRAY 2 ");
console.log(arr2);
painotpi
  • 6,894
  • 1
  • 37
  • 70
-1

You would use what is called the spread operator which creates a copy and allows you to modify it. example:

let newElement = 1;
const modifiedArray = [...oldArray, newElement];

There are also other javascript methods like slice() that will return a modified copy of an array.

Sean Dillon
  • 140
  • 8
  • 1
    They are mutating the object inside the array. `[...oldArray]` only creates a copy of the array – adiga May 15 '21 at 13:52