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; }