A deep copy in JavaScript refers to the creation of a new object or array that contains copies of all the properties or elements of the original object or array, including nested objects and arrays. In other words, each property or element of the original object or array is recursively copied, resulting in a new object or array that is independent of the original one.
Problem
const source = {
prop: "Property",
object: { array: [10, 20, 30] },
};
const copy = { ...source };
copy.object.array[0] = 100;
console.log(source);
The spread syntax { ...source }
creates a shallow copy of the source
object. While the top-level properties of source
are copied into copy
, the object
property within source
still holds a reference to the same array as the object
property in copy
.
Solution #1
Use the spread operator. The copy
and source
will not share the same reference to the array property.
const source = {
prop: "Property",
object: { array: [10, 20, 30] },
};
const copy = { ...source, object: { array: [...source.object.array] } };
copy.object.array[0] = 100;
console.log(source);
When you modify the first element of the array
property in the copy
variable, it does not affect the source
object because copy
and source
have separate references to their object properties and separate references to the array
property within those objects. Therefore, changing the value of copy.object.array[0]
to 100 does not alter the source object.
Solution #2
To perform a simple deep clone, you can use methods like JSON.parse(JSON.stringify( object))
.
const source = {
prop: "Property",
object: { array: [10, 20, 30] },
};
const copy = JSON.parse(JSON.stringify(source));
copy.object.array[0] = 100;
console.log(source);
Pitfalls
JSON.parse(JSON.stringify())
works only for simple data types like objects and arrays. It cannot clone functions, RegExp, Date, Map, Set, or undefined values, as they are not valid JSON data types. JSON.parse(JSON.stringify())
cannot handle circular references in objects.
While JSON.parse(JSON.stringify())
is a quick and easy way to shallow clone simple objects and arrays, it is not suitable for deep cloning in more complex scenarios.
Solution #3
structuredClone()
is a JavaScript function that creates a deep copy of an object or value, including nested objects and arrays. It is similar to JSON.parse(JSON.stringify())
, but with some differences:
structuredClone()
can handle circular references.structuredClone()
can clone a wider range of JavaScript values, including functions, dates, regular expressions, Maps, Sets, Blobs, FileLists, and ImageDatas.
const source = {
prop: "Property",
object: { array: [10, 20, 30] },
};
const copy = structuredClone(source);
copy.object.array[0] = 100;
console.log(source);
For further details, please visit https://developer.mozilla.org/en-US/docs/Web/API/structured Clone.