Introduction
Cloning JS object is pretty common task in our day-to-day life. Lets discuss techniques about it.
PS. Use structuredClone
for proper cloning as it's now available in native JS.
Shallow Cloning and Deep Cloning
Lets first discuss what actually is shallow cloning and deep cloning:
Shallow cloning and deep cloning are two different approaches to copying objects in JavaScript, and they have distinct characteristics and use cases:
Shallow Cloning:
Shallow cloning creates a new object, but it only copies the top-level properties of the original object. If the properties of the original object are references to other objects, those references are shared between the original and cloned objects.
Deep Cloning:
Deep cloning creates a completely new object with all of its properties and nested properties duplicated. It ensures that no references are shared between the original and cloned objects, resulting in a fully independent copy.
Shallow Cloning
1. Object.assign()
The Object.assign()
method is a concise way to perform shallow cloning of JavaScript objects. It creates a new object and copies enumerable properties from the original object to the new one. However, be aware that if the properties in the original object are objects or arrays, they will be copied by reference.
const clonedObject = Object.assign({}, originalObject);
2. Spread Operator (ES6)
The spread operator is another method for shallow cloning objects introduced in ES6. It provides a more modern and concise syntax for creating a shallow copy of an object.
const clonedObject = { ...originalObject };
Deep Cloning
3. JSON.parse() and JSON.stringify()
To create a deep clone of an object, you can use JSON.parse()
and JSON.stringify()
. This method serializes the original object to a JSON string and then parses it back into a new object. It's great for deep cloning but has limitations, such as not handling functions, symbols, or circular references.
const clonedObject = JSON.parse(JSON.stringify(originalObject));
4. Structured Clone
In web worker environments, you can use the structuredClone
method to clone objects. This method can handle more complex data types but is specific to web workers.
Comparing Deep Cloning Methods
Let's say you have an object with a function property:
const originalObject = {
name: "John",
age: 30,
greet: function () {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
},
};
Now, let's try to clone this object using both methods: JSON.parse(JSON.stringify())
and structuredClone
.
- Using
JSON.parse(JSON.stringify())
:
const cloneWithJSON = JSON.parse(JSON.stringify(originalObject));
// Attempt to call the function in the cloned object
cloneWithJSON.greet(); // Throws an error: cloneWithJSON.greet is not a function
As you can see, the function property is lost during the cloning process. JSON.stringify serializes the object to JSON, and JSON.parse creates a new object from the JSON representation. Functions are not valid JSON, so they are omitted.
- Using
structuredClone
:
const clonedObject = structuredClone(originalObject);
// Attempt to call the function in the cloned object
clonedObject.greet(); // Works as expected: "Hello, my name is John and I am 30 years old."
With structuredClone
, the cloning process preserves the function property, and you can call it on the cloned object without any issues. This method is more powerful and versatile when working with complex objects that contain non-serializable properties.
Conclusion
For shallow cloning, consider using the spread operator or
Object.assign()
for their simplicity.When deep cloning is required and your object doesn't contain functions, symbols, or circular references, opt for
JSON.parse()
andJSON.stringify()
.structuredClone
method is your best bet as it is now natively available and also helps cloning Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, sparse Arrays, Typed Arrays.
Follow me for more such content:
LinkedIn: https://www.linkedin.com/in/shameeluddin/
Github: https://github.com/Shameel123