Table of contents
1.
Introduction  
2.
Shallow copy
2.1.
C++
2.2.
Java
2.3.
Python
2.4.
Javascript
3.
Deep copy
3.1.
C++
3.2.
Java
3.3.
Python
3.4.
Javascript
4.
Difference Between Shallow Copy and Deep Copy
5.
How to solve the problem of shallow copying
5.1.
Spread syntax
5.2.
Javascript
5.3.
object.assign() method
5.4.
Javascript
5.5.
JSON.parse() method
5.6.
Javascript
6.
Different Scenarios Where Deep and Shallow Copies Are Similar
6.1.
1. Simple Data Structures
6.2.
2. Immutable Objects
6.3.
3. Simple Object with Non-Nested Properties
6.4.
4. Unchanged Nested Structures
6.5.
5. Read-Only Operations
7.
Frequently Asked Questions
7.1.
Is Python copy shallow or deep?
7.2.
Is NumPy copy a deepcopy?
7.3.
Is clone() a deep copy?
7.4.
What is a reference object in javascript?
7.5.
What is an object in javascript?
7.6.
What is the use of object.create() method in javascript?
8.
Conclusion
Last Updated: Aug 4, 2024
Easy

Difference Between Shallow Copy and Deep Copy

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction  

In programming, particularly when dealing with complex data structures like arrays or objects, understanding the concepts of shallow copy and deep copy is crucial. These copying mechanisms dictate how data is replicated and manipulated, affecting both performance and behavior in your applications.

A shallow copy duplicates an object’s top-level properties but does not recursively copy nested objects. This means that while the outer object is a new instance, its nested objects are still references to the same instances as the original. On the other hand, a deep copy creates a complete clone of the entire object, including all nested objects, ensuring that the new object is entirely independent of the original. In this blog, we will delve into the fundamental differences between shallow and deep copies.

Difference Between Shallow Copy and Deep Copy

Shallow copy

A shallow copy is mainly a reference variable that stores the address of the object it is copied from. We are creating a new object with the same value as that of the original object. But if we change the values in this object, it will be affected in the original object also. So both objects share the same memory locations. Let's understand this with an example.

If we consider an object obj1 and store a name-value, say ‘Rajveer’ in it. Now we create another object name obj2 and copy obj1 into it. So in shallow copy, both the objects share the same memory allocation, and hence if we change the value of obj2, then the value of obj1 will also be changed.

It is making a copy of the reference of obj1 into obj2. It is pointing both obj1 and obj2 to the same memory locations. So when the value of one is changed, the other is changed automatically.

shallow copy

 

Now lets understand this using a code in javascript:

Implementation:

  • C++
  • Java
  • Python
  • Javascript

C++

#include <iostream>
#include <cstring>

class Developer {
public:
std::string name;
int age;

Developer(const std::string& name, int age) : name(name), age(age) {}

// Copy assignment operator for shallow copy
Developer& operator=(const Developer& other) {
if (this == &other) return *this;
name = other.name;
age = other.age;
return *this;
}
};

int main() {
Developer develop1("Ranveer", 30);
Developer develop2 = develop1; // Shallow copy

std::cout << develop1.name << ", " << develop1.age << " (develop1)" << std::endl;
std::cout << develop2.name << ", " << develop2.age << " (develop2)" << std::endl;

std::cout << "Modifying develop2" << std::endl;
develop2.age = 21;

std::cout << develop1.name << ", " << develop1.age << " (develop1)" << std::endl;
std::cout << develop2.name << ", " << develop2.age << " (develop2)" << std::endl;

return 0;
}
You can also try this code with Online C++ Compiler
Run Code

Java

public class Developer {
String name;
int age;

Developer(String name, int age) {
this.name = name;
this.age = age;
}

public static void main(String[] args) {
Developer develop1 = new Developer("Ranveer", 30);
Developer develop2 = develop1; // Shallow copy

System.out.println(develop1.name + ", " + develop1.age + " (develop1)");
System.out.println(develop2.name + ", " + develop2.age + " (develop2)");

System.out.println("Modifying develop2");
develop2.age = 21;

System.out.println(develop1.name + ", " + develop1.age + " (develop1)");
System.out.println(develop2.name + ", " + develop2.age + " (develop2)");
}
}
You can also try this code with Online Java Compiler
Run Code

Python

class Developer:
def __init__(self, name, age):
self.name = name
self.age = age

# Create an instance of Developer
develop1 = Developer("Ranveer", 30)

# Shallow copy (reference copy)
develop2 = develop1

print(f'{develop1.name}, {develop1.age} (develop1)')
print(f'{develop2.name}, {develop2.age} (develop2)')

print('Modifying develop2')
develop2.age = 21

print(f'{develop1.name}, {develop1.age} (develop1)')
print(f'{develop2.name}, {develop2.age} (develop2)')
You can also try this code with Online Python Compiler
Run Code

Javascript

const develop1 = {
   name: 'Ranveer',
   age: 30
};


const develop2 = develop1;
console.log(develop1, 'develop1');
console.log(develop2, 'develop2');


console.log('modifying develop2');
develop2.age = 21;


console.log(develop1, 'develop1');
console.log(develop2, 'develop2');
You can also try this code with Online Javascript Compiler
Run Code

Output:

output

So we can clearly see that when we changed develop2 , values of develop1 also changed.

Deep copy

Unlike shallow copy, deep copy copies all the fields and the memory allocated to it. Since it allocates different memory, it helps to create copied or cloned objects without worries of changing the old object. Let us understand this with examples.

If we consider an obj1 and store name and age in it say “Salman” ,“50”.Then we create a new obj2 and can copy obj1 into it. So in deep copying, when we change the value of obj2, there will be no changes in the value of obj1.

It is copying all values of obj1 and then assigning different memory locations to obj2. Hence if values of obj1 are changed or obj1 deletes, then there will be no changes in obj2.

deep copy

Now let us understand this using a code in javascript.

Implementation:

  • C++
  • Java
  • Python
  • Javascript

C++

#include <iostream>
#include <string>

class Developer {
public:
std::string name;
int age;

// Constructor
Developer(const std::string& name, int age) : name(name), age(age) {}

// Copy constructor for deep copy
Developer(const Developer& other) : name(other.name), age(other.age) {}

// Assignment operator for deep copy
Developer& operator=(const Developer& other) {
if (this == &other) return *this;
name = other.name;
age = other.age;
return *this;
}
};

int main() {
Developer develop1("Rajveer", 40);

// Deep copy
Developer develop2 = develop1;

std::cout << "develop1: " << develop1.name << ", " << develop1.age << std::endl;
std::cout << "develop2: " << develop2.name << ", " << develop2.age << std::endl;

std::cout << "Modifying develop2" << std::endl;
develop2.name = "Sushant";
develop2.age = 20;

std::cout << "develop1: " << develop1.name << ", " << develop1.age << std::endl;
std::cout << "develop2: " << develop2.name << ", " << develop2.age << std::endl;

return 0;
}
You can also try this code with Online C++ Compiler
Run Code

Java

public class Developer {
String name;
int age;

Developer(String name, int age) {
this.name = name;
this.age = age;
}

// Copy constructor for deep copy
Developer(Developer other) {
this.name = other.name;
this.age = other.age;
}

public static void main(String[] args) {
Developer develop1 = new Developer("Rajveer", 40);

// Deep copy
Developer develop2 = new Developer(develop1);

System.out.println("develop1: " + develop1.name + ", " + develop1.age);
System.out.println("develop2: " + develop2.name + ", " + develop2.age);

System.out.println("Modifying develop2");
develop2.name = "Sushant";
develop2.age = 20;

System.out.println("develop1: " + develop1.name + ", " + develop1.age);
System.out.println("develop2: " + develop2.name + ", " + develop2.age);
}
}
You can also try this code with Online Java Compiler
Run Code

Python

import copy

class Developer:
def __init__(self, name, age):
self.name = name
self.age = age

# Create an instance of Developer
develop1 = Developer("Rajveer", 40)

# Deep copy
develop2 = copy.deepcopy(develop1)

print(f'develop1: {develop1.name}, {develop1.age}')
print(f'develop2: {develop2.name}, {develop2.age}')

print("Modifying develop2")
develop2.name = "Sushant"
develop2.age = 20

print(f'develop1: {develop1.name}, {develop1.age}')
print(f'develop2: {develop2.name}, {develop2.age}')
You can also try this code with Online Python Compiler
Run Code

Javascript

const develop1 = {
   name: "Rajveer",
   age: 40
}


const develop2 = JSON.parse(JSON.stringify(develop1));
console.log("develop1 ",develop1);
console.log("develop2 ",develop2);


console.log("modifying develop2");
develop2.name = "Sushant";
develop2.age = 20;


console.log("develop1 ", develop1);
console.log("develop2 ", develop2);
You can also try this code with Online Javascript Compiler
Run Code

Output:

output

We can clearly see that even when develop2 is changed , develop1 remains same.

Difference Between Shallow Copy and Deep Copy

Aspect Shallow Copy Deep Copy
Definition Copies the top-level properties or references of the object. Creates a new object and recursively copies all nested objects.
Nested Objects Nested objects are still references to the same instances as the original. Nested objects are fully cloned, creating new instances for all nested objects.
Memory Usage Generally uses less memory since nested objects are shared. Uses more memory because it duplicates all nested objects.
Performance Faster since only the top-level structure is copied. Slower due to the additional overhead of copying nested structures.
Mutability Changes to nested objects in the copied object affect the original. Changes to nested objects in the copied object do not affect the original.
Copy Method Achieved using simple assignment or shallow copy functions (e.g., Object.assign in JavaScript, or copy.copy in Python). Achieved using deep copy functions (e.g., JSON.parse(JSON.stringify(...)) in JavaScript, copy.deepcopy in Python).
Use Case Suitable for simple or non-nested structures where you want to preserve references. Suitable for complex or nested structures where complete independence of objects is required.

How to solve the problem of shallow copying

There are three ways of copying an object in javascript.

  1. Spread syntax
  2. Using object.assign() method
  3. Using JSON.parse() and JSON.stringify() method

Spread syntax

Here spread method and object.assign() method performs a shallow copying while JSON.parse() and JSON.stringify() method perform a deep copying.

Example for spread syntax copying :

Implementation:

  • Javascript

Javascript

let person = {
   firstName: 'raj',
   lastName: 'arora',
     address: {
     city: 'delhi',
     state: 'india',
   }
};



let copiedPerson = {
   ...person
};


copiedPerson.firstName = 'Jane';
copiedPerson.address.city = 'agra';



console.log(person);
console.log(copiedPerson);
You can also try this code with Online Javascript Compiler
Run Code

Output:

output

Here we can clearly see that firstName didn't change while the city changed. This is because the first name is a primitive value while address is reference value.Both of these are referenced to different object by addressed to similar address.

object.assign() method

Object.assign() method is similar to spread syntax. Both of these perform shallow copying. Example for object.assign() method copying.

Implementation:

  • Javascript

Javascript

let person = {
   firstName: 'raj',
   lastName: 'arora',
     address: {
     city: 'delhi',
     state: 'india',
   }
};



let copiedPerson = Object.assign({}, person);


copiedPerson.firstName = 'Jane';
copiedPerson.address.city = 'agra';



console.log(person);
console.log(copiedPerson);
You can also try this code with Online Javascript Compiler
Run Code

Output:

output

JSON.parse() method

This method perform a deep copying so when copied object is changed there are no changes in original object.example of JSON.parse() method is:

Implementation:

  • Javascript

Javascript

let person = {
   firstName: 'raj',
   lastName: 'arora',
     address: {
     city: 'delhi',
     state: 'india',
   }
};



let copiedPerson = JSON.parse(JSON.stringify(person));


copiedPerson.firstName = 'Jane';
copiedPerson.address.city = 'agra';



console.log(person);
console.log(copiedPerson);
You can also try this code with Online Javascript Compiler
Run Code

Output:

output

We can clearly see that even when copied person is changed, there are no changes in the person object.

You can also read about the memory hierarchy.

Different Scenarios Where Deep and Shallow Copies Are Similar

Here are some scenarios where shallow and deep copies can exhibit similar behavior or outcomes, despite their fundamental differences:

1. Simple Data Structures

Scenario: When copying simple data structures that don’t contain nested objects or complex references.

  • Example: Copying a list or an array of primitive values (e.g., integers, strings).
  • Shallow Copy: Creates a new list or array, but since there are no nested objects, the result is effectively the same as a deep copy.
  • Deep Copy: Also results in a new list or array with the same primitive values. No difference from shallow copy in this case.

Explanation: In cases where the data structure is flat and consists solely of primitive values, both shallow and deep copies result in identical outcomes, as there are no nested objects or references to consider.

2. Immutable Objects

Scenario: When working with immutable objects where the object's state cannot be modified.

  • Example: Strings or tuples in Python, or String objects in Java.
  • Shallow Copy: Creates a new reference to the same immutable object.
  • Deep Copy: Also results in a new reference to the same immutable object, as immutable objects cannot be modified.

Explanation: Since immutable objects cannot be changed once created, both shallow and deep copies result in equivalent outcomes because the object's content remains the same.

3. Simple Object with Non-Nested Properties

Scenario: When copying objects that contain only non-nested properties.

  • Example: An object with only primitive data types as properties.
  • Shallow Copy: Copies the object with all primitive properties, resulting in a new object that is functionally identical to the original.
  • Deep Copy: Also copies the primitive properties, leading to the same result as a shallow copy.

Explanation: When an object doesn’t contain any nested structures or references, both shallow and deep copies behave similarly, as they both effectively create a new object with the same values.

4. Unchanged Nested Structures

Scenario: When copying objects with nested structures where the nested objects themselves are not modified after copying.

  • Example: A complex object is copied, but neither the original nor the copied object modifies the nested structures.
  • Shallow Copy: Copies the top-level structure, and since nested structures are not altered, the outcome is similar to a deep copy.
  • Deep Copy: Results in a new object with new instances of nested structures. Since no modifications are made, both copies behave similarly.

Explanation: If no modifications are made to the nested structures after copying, the differences between shallow and deep copies are not apparent in terms of the object's behavior.

5. Read-Only Operations

Scenario: When the copied object is only used for read-only operations and is not modified.

  • Example: Copying an object to perform read operations without changing its state.
  • Shallow Copy: Provides a new reference to the same data for read-only purposes.
  • Deep Copy: Also provides a new reference to the same data for read-only purposes, with no observable difference.

Explanation: If the copied object is used only for reading and not for modifying, both shallow and deep copies can be functionally equivalent because no changes to nested structures are made.

Also see, Difference Between Compiler and Interpreter and Assembler

Frequently Asked Questions

Is Python copy shallow or deep?

Python’s copy module provides both shallow (copy.copy()) and deep copies (copy.deepcopy()) depending on the function used.

Is NumPy copy a deepcopy?

NumPy's copy() function performs a shallow copy; for deep copies, nested arrays require additional handling.

Is clone() a deep copy?

In Java, clone() performs a shallow copy by default; deep copying requires explicit implementation.

What is a reference object in javascript?

In javascript, the object reference is information on how to find that object.it is the reference to that object to get to the memory.

What is an object in javascript?

Objects in javascript are also variable but they store many values together.
To declare variables we use the let key while for objects we use the const key. for example:
Const book = {name;”secret” , author:”Xyz” , price:”rs.500”};

What is the use of object.create() method in javascript?

Object.create() method is used to create a new object using the prototype of an existing object.for example:
Const a=object.create(x);

Conclusion

In this blog, we have discussed about shallow copy and deep copy. We also learned the difference between shallow copy and deep copy. Also we learned a few coping mechanisms to overcome shallow copy using javascript language. We hope that this blog has helped you enhance your knowledge regarding program to convert pascal case string to snake case string and if you would like to learn more, check out our articles on javascript. Do upvote our blog to help other ninjas grow. Happy Coding!”

Live masterclass