Reputation: 13
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
Upvotes: 0
Views: 434
Reputation: 8660
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);
Upvotes: 0
Reputation: 25383
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 i.e., 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.
Upvotes: 1