How to clone Object in JavaScript

How to clone Object in JavaScript

·

4 min read

Cloning objects in JavaScript is a common task encountered in interviews and practical coding scenarios. There are various methods to achieve this, each with its own advantages and limitations. In this guide, we'll explore shallow cloning versus deep cloning and discuss different techniques along with their pros and cons.

Shallow cloning VS Deep cloning

Before delving into the disparity among these methods, grasping the concepts of shallow and deep copying is imperative.

Shallow Cloning or shallow copy

Shallow copy duplicates the original object's properties but maintains references to nested objects. Consequently, modifications to nested objects in the copied instance affect the original.

In short, Shallow cloning creates a new object with copies of the original object's properties, but it does not deeply clone nested objects.

Deep Cloning or deep copy

On the other hand deep copy replicates the original object and all its properties and nested objects. Both objects become entirely independent, ensuring changes to one don't impact the other.

Method 1 : Object.assign()

To shallow copy an object in JavaScript, utilize the Object.assign() method, which accepts two objects as arguments (the target and the source) and returns an exact replica of the source object..

const targetObj = { userName: "rubi", email: "rubi@gmail.com" };
const sourceObj = { userName: "vaibhav", email: "vaibhav@gmail.com" };

const returnedTarget = Object.assign(targetObj, sourceObj);

console.log(targetObj);
// Expected output: Object { userName: "vaibhav", email: "vaibhav@gmail.com" }

console.log(returnedTarget === targetObj);
// Expected output: true
const user = {
  userName: "vaibhav", 
  email: "vaibhav@gmail.com",
  address : {
    city : "Ambala",
    country : "India"
  }
}

const newUser = Object.assign({}, user)

console.log(newUser);
// Expected output: Object { userName: 'vaibhav', email: 'vaibhav@gmail.com', address: { city: 'Ambala', country: 'India' } }

In the given example, we initialize an object named user containing user information, including a nested address object. Subsequently, we shallow copy the user object using Object.assign() into a new object named newUser.

It's important to note that although newUser is a shallow copy of user, any modifications made to nested properties within newUser will also affect the corresponding properties in the original user object.

This phenomenon is illustrated in the explanation provided: if we alter the address property within newUser, it will concurrently modify the address property within the user object as well.

Method 2 : Spread operator

Another approach for shallow copying is using the spread operator (...). The spread operator facilitates the expansion of an object's properties into a new object. Here's an example:

const user = {
  userName: "vaibhav", 
  email: "vaibhav@gmail.com",
  address : {
    city : "Ambala",
    country : "India"
  }
}

const newUser = { ... user }

console.log(newUser);
// Expected output: Object { userName: 'vaibhav', email: 'vaibhav@gmail.com', address: { city: 'Ambala', country: 'India' } }

Method 3 : JSON.parse() and JSON.stringify()

A common approach for deep copying an object in JavaScript involves using the JSON.parse() and JSON.stringify() methods. JSON.stringify() converts a JavaScript object into a JSON string, while JSON.parse() converts a JSON string back into a JavaScript object.

Here's an example showcasing these methods:

const user = {
  userName: "vaibhav", 
  email: "vaibhav@gmail.com",
  address : {
    city : "Ambala",
    country : "India"
  }
};

const newUser =  JSON.parse(JSON.stringify(user));
newUser.address.city = "Los Angeles";
newUser.address.country = "US"

console.log(newUser);
// Expected output: Object { userName: 'vaibhav', email: 'vaibhav@gmail.com', address: { city: 'Los Angeles', country: 'US' } }

console.log(user);
// Expected output: Object { userName: 'vaibhav', email: 'vaibhav@gmail.com', address: { city: 'Ambala', country: 'India' } }Expected output: Object { userName: 'vaibhav', email: 'vaibhav@gmail.com', address: { city: 'Ambala', country: 'India' } }

In this example, the original object is first converted into a JSON string using JSON.stringify(). Subsequently, a new object is created by parsing the JSON string with JSON.parse(). This method ensures a deep copy of the original object, including all nested objects.

However, it's essential to note some limitations:

  • Performance may suffer for large objects due to string conversion and parsing.

  • Works only with objects that can be serialized to JSON. Objects with circular references, functions, or non-serializable properties (such as Date, RegExp, or Map and Set) cannot be cloned using this method.

Method 4 : structuredClone()

Another approach for deep copying involves using the structured cloning algorithm. structuredClone() is not a built-in JavaScript function; it's part of the structured cloning algorithm provided by the HTML Living Standard. It's typically available in environments such as web workers and service workers.

const user = {
  userName: "vaibhav", 
  email: "vaibhav@gmail.com",
  address : {
    city : "Ambala",
    country : "India"
  }
};

const newUser =  structuredClone(user);
newUser.address.city = "Gurugram";

console.log(newUser);
// Expected output: Object { userName: 'vaibhav', email: 'vaibhav@gmail.com', address: { city: 'Gurugram', country: 'India' } }

console.log(user);
// Expected output: Object { userName: 'vaibhav', email: 'vaibhav@gmail.com', address: { city: 'Ambala', country: 'India' } }

Considerations:

  • Performance: JSON methods might be slower for large objects due to string conversion.

  • Compatibility: JSON methods only work with serializable objects, excluding functions and non-serializable properties.

  • Availability: structuredClone() is available in environments like web and service workers.

  • Libraries: Libraries like Lodash and Ramda offer robust solutions for deep cloning, accommodating complex data structures and edge cases.

Object cloning in JavaScript is a nuanced process with various approaches catering to different scenarios. Understanding these techniques equips developers to efficiently manage object data in their projects.