Javascript Series: Understanding Shallow and Deep Copy

Javascript Series: Understanding Shallow and Deep Copy

In JavaScript, when working with objects and arrays, it is important to understand the concepts of shallow copy and deep copy. These terms refer to different ways of creating copies of objects or arrays, and they have distinct implications for how data is shared or duplicated. Let’s explore the differences between shallow copy and deep copy and how they are used in JavaScript.

Shallow Copy

Shallow copy is a method of copying where the new object or array references the same memory location as the original object or array. In other words, it creates a new reference to the original data structure without duplicating its contents. Any changes made to the copied object or array will be reflected in the original, and vice versa.

const originalArray = [1, 2, 3];
const shallowCopyArray = originalArray;

shallowCopyArray.push(4);

console.log(originalArray); // Output: [1, 2, 3, 4]
console.log(shallowCopyArray); // Output: [1, 2, 3, 4]

In the example above, the shallowCopyArray is a shallow copy of the originalArray. Modifying either of them will affect both arrays because they reference the same memory location. This behavior can be problematic if you want to have independent copies that do not affect each other.

Deep Copy

Deep copy, on the other hand, creates an entirely new object or array with its own memory allocation. It recursively copies all nested objects and arrays, ensuring that any changes made to the copied object or array do not affect the original.

Method 1: Using JSON.parse() and JSON.stringify()

One way to achieve deep copy is by using the combination of JSON.parse() and JSON.stringify() methods. This method converts the object or array to a JSON string and then parses it back into a new object or array.

const originalObject = { name: "John", age: 25 };
const deepCopyObject = JSON.parse(JSON.stringify(originalObject));

deepCopyObject.age = 30;

console.log(originalObject); // Output: { name: "John", age: 25 }
console.log(deepCopyObject); // Output: { name: "John", age: 30 }

Method 2: Using the spread operator (for shallow nested objects)

The spread operator (…) can be used to achieve a deep copy for shallow nested objects or arrays.

const originalObject = { name: "John", address: { city: "New York", country: "USA" } };
const deepCopyObject = { ...originalObject };

deepCopyObject.address.city = "San Francisco";

console.log(originalObject); // Output: { name: "John", address: { city: "New York", country: "USA" } }
console.log(deepCopyObject); // Output: { name: "John", address: { city: "San Francisco", country: "USA" } }

Method 3: Using libraries or utility functions

There are several libraries and utility functions available that provide deep copy functionality, such as lodash.cloneDeep() or jQuery.extend(true, {}, originalObject).

const originalObject = { name: "John", age: 25 };
const deepCopyObject = _.cloneDeep(originalObject); // Using lodash library

deepCopyObject.age = 30;

console.log(originalObject); // Output: { name: "John", age: 25 }
console.log(deepCopyObject); // Output: { name: "John", age: 30 }

Choosing Between Shallow Copy and Deep Copy

The choice between shallow copy and deep copy depends on the specific use case and the desired behavior. Consider the following guidelines:

  • Use shallow copy when you want to create a new reference to the same data structure and maintain the ability to update the original object or array.
  • Use deep copy when you need to create an independent copy that does not affect the original data structure.

It’s important to note that deep copying complex objects or arrays can be resource-intensive and may impact performance. In such cases, consider using libraries or built-in methods designed to handle deep copying efficiently.

Conclusion

Understanding shallow copy and deep copy in JavaScript is crucial for managing data structures effectively. Shallow copy creates a new reference to the original object or array, while deep copy creates an entirely new data structure. By choosing the appropriate copy method, you can control how changes to copied data affect the original data. Keep these concepts in mind when working with objects and arrays in JavaScript to ensure proper data management and prevent unexpected side effects.