简体   繁体   中英

Best practice for copying array with objects

I don't understand how work copying for arrays and what is the best way to copying objects from an array.

When I create a new array which is a copy of my existing array by spread operator or method slice() any actions still change the values in both arrays.

example:

let array = [{count: 10}, {count: 20}, {count: 30}, {count: 40}];
let newArray = array.slice();

newArray[1].count = 0;
// console.log(array[1].count === newArray[1].count);
// > true

This means that I should use JSON.parse(JSON.stringify(array))?

example:

let array = [{count: 10}, {count: 20}, {count: 30}, {count: 40}];
let arrayByJSON = JSON.parse(JSON.stringify(array));

arrayByJSON[1].count = 5;
// console.log(array[1].count === arrayByJSON[1].count)
// false

I think the confusion here is over deep vs. shallow clones, which basically comes down to if references are followed or not.

Shallow copy : Shallow copy is a bit-wise copy of an object. A new object is created that has an exact copy of the values in the original object. If any of the fields of the object are references to other objects, just the reference addresses are copied ie, only the memory address is copied.

Deep copy : A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy occurs when an object is copied along with the objects to which it refers.

In general, Use slice /spread for shallow clones, and JSON.parse/stringify for deep clones.

In your case, use JSON.parse(JSON.stringify(array)) because you don't want references preserved during the clone.

More info here .

You can copy elements of an array by using .slice or [...] however, the things that cannot be copied this way are multi-dimensional arrays or objects since they are stored as references.

Using JavaScript syntax we can easily determine if an item is an Array or an Object and copy them using appropriate methods.

Objects can be copied by using Object.assign({}, obj) . Arrays can be copied by using .slice() . In the code, however, we want to iterate through the internal array as well since you never know if that internal array will also contain more Arrays or Objects. We can make sure this problem doesn't cause us any hassle by simply recursively calling our deep copy function when we run into instances of an Array.

function deepCopyArray(arr) {
  return arr.map(item => {
    if (Array.isArray(item)) {
      return deepCopyArray(item);
    }
    if (typeof item === "object") {
      return Object.assign({}, item);
    }
    else return item;
  });
}

 function deepCopyArray(arr) { return arr.map(item => { if (Array.isArray(item)) { return deepCopyArray(item); } if (typeof item === "object") { return Object.assign({}, item); } else return item; }); } let array = [{ count: 10 }, { count: 20 }, { count: 30 }, { count: 40 }]; let newArray = deepCopyArray(array); newArray[1].count = 0; console.log(newArray, array); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM