10

I tried this approach:

this.plans = [];
this.plansCopy = [...this.plans];

Seems it does not work cause returns duplictions.

Alice
  • 207
  • 2
  • 3
  • 10

2 Answers2

26

The spread operator returns the individual items of the array. If these are already objects, then it's returning the references to those objects. It's the [] part that is creating a new array. Thus you have a new array, but it will still contain the same object references, so this.plans[0].oper() will call this.plansCopy[0].oper() at the same time as well.

Instead you need to clone each individual object. There are a lot of different ways to do this (create deep copy of the array or individual objects). If you only need one level of cloning you can do:

this.plansCopy = this.plans.map(obj => ({...obj}));

This will create a new array where each element is a copy of each object.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
10

This is well answered here. The main problem is that you can have the issue of copying a reference, rather than duplicating it, at deeper levels of the array. If you know you only have simple objects, you can also use

const newArray = Array.from(oldArray); 

which I find clearer than the spread operator.

However, if you don't know how deep the complexity of your array goes (i.e. how deeply nested you might have a non-simple type) the generic answer seems to be

this.backupData = JSON.parse(JSON.stringify(genericItems));

As this will go all the way down the array's objects, and build them back up -- cloning for the general case.

Community
  • 1
  • 1
Ben
  • 560
  • 4
  • 6