0

I have an object array let a = [{aa: 1, bb: 2}]. I am creating a 2 new arrays from a let b = [...a] and let c = [...a]. When I modify the data in the object from array c, it gets reflected in array b too. I want to modify the array c without affecting the array b.

I tried to splice(0) and create the new arrays from the other Stack Overflow answers but that too didn't work. It doesn't even work in js console. Any way to fulfill my requirement?

let a = [{aa: 1, bb: 2}];
let b = [...a];
let c = [...a];

c[0].aa = 11;

console.log(JSON.stringify(b)); // Why is `aa` this 11 and not 1?
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
Joshua
  • 1,167
  • 1
  • 14
  • 32

1 Answers1

0

There are two ways to deep clone an object, serialize-deserialize or map the clone of each item. You will have to account for each level though.

const deepCloneOld = data => JSON.parse(JSON.stringify(data));
const deepCloneNew = data => data.map(record => ({...record}));

let a = [{aa: 1, bb: 2}];
let b = deepCloneNew(a);
let c = deepCloneNew(a);

c[0].aa = 11;

console.log(JSON.stringify(b)); // `aa` is still 1

Performance test

In the example below, the "new" way will run 200-300% faster than the "old" way.

Alternatively, here is a jsperf.

const rounds = 100;
const heats = 1000;

const objectToClone = [{ a: 1, b: 2, c: 3 }];

const deepCloneOld = data => JSON.parse(JSON.stringify(data));
const deepCloneNew = data => data.map(record => ({...record}));

const main = () => {
  perfTest('Duration (Old):', () => deepCloneOld(objectToClone), rounds, heats);
  perfTest('Duration (New):', () => deepCloneNew(objectToClone), rounds, heats);
};

const perfTest = (label, fn, rounds, heats) => {
  let times = [];
  for (let round = 0; round < rounds; round++) {
    let ticks = [];
    for (let heat = 0; heat < heats; heat++) {
      ticks.push(new Date().getTime());
      fn();
      ticks[ticks.length - 1] = new Date().getTime() - ticks[ticks.length - 1];
    }
    times.push(ticks.reduce((r, t) => r + t, 0) / ticks.length);
  }
  console.log(label, times.reduce((r, t) => r + t, 0) / times.length);
};

main();
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132