Difference between Deep and Shallow Copy in Javascript.
In this article we are going to learn about copy , shallow copy , deep copy and understand about how to differentiate between deep and shallow copies.
First of all Let's understand, what does means by copy. π
A copy in programming means when we store values in variables. By making a copy, you initiate a new variable with the same values. When you change the copy, you expect the original thing to stay the same, whereas the copy changes.
let a = 5
let b = a // here we copy the value from `a` and store it `b`
b = 6 // Now in this line we update the value `b`
console.log(b) // 6
console.log(a) // 5
Now we can clearly see in the above example that executing b = a
, you make the copy. When you reassign a new value to b
, the value of b
changes, but a
value remains the same. So, we understood how copy has been done in programming.
Now, things become more interesting let's consider we are working on Objects and Arrays (In Non-Primitive Datatypes). These values are actually stored just once when instantiated, and assigning a variable just creates a reference to that value. If we are going to make a copy b = a
in an object or array and change some nested value in b, it actually changes aβs nested value as well, since a and b both point to the same thing.
Let's understand by an example -
const person = {
firstName:"Kushal",
lastName:"Das",
age:22,
};
let copy_person = person // here we copied `person` and store in `person_copy`
copy_person.age = 21 // here we changed `age` value to `21` in `copy_person`
console.log(copy_person.age) // 21
console.log(person.age) //21
In the example above we first copied person
and store this in copy_person
variable, then we update the age
value as a result we can see that the original object
is also being affected along with the copy one (copy_person)
, and this is because we made a shallow copy.
So A shallow copy of an object is a copy whose properties share the same references, if any of the fields of the object are references to other objects, just the reference addresses are copied that means only the memory address is copied
In the above example, we can say it makes a copy of the reference to person
into copy_person
. So here are the addresses of person
and copy_person
will be the same i.e. they will be pointing to the same memory location.
This is oftentimes problematic since we expect the old variable
to have the original values
, not the changed ones
.
So If we instead want to copy an object
so that we can modify it without affecting the original object
, we need to make a deep copy.
A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy is not going to change the original values if we do some changes in clone object because they will be pointing to the different memory location.
There are many ways to make a deep copy in JavaScript we will discuss a few of them.
Using Spread operator π
JavaScript is with the ES6 spread operator. Using the three dots (...) collect all values on the original object into another object.
// Deep copy using Spread operator
const person = {
firstName:"Kushal",
lastName:"Das",
age:22,
};
let copy_person = {...person} // here we copied `person` and store in `person_copy`
//using Spread operator
copy_person.age = 21 // here we changed `age` value to `21` in `copy_person`
console.log(copy_person.age) // 21
console.log(person.age) //22
Using Object.assign π
This was mostly used before the spread operator was around, and it basically does the same thing. You have to be careful though, as the first argument in the Object.assign() method actually gets modified and returned. So make sure that you pass the object to copy at least as the second argument. Normally, you would just pass an empty object as the first argument to prevent modifying any existing data.
// deep copy using Object.assign
const person = {
firstName:"Kushal",
lastName:"Das",
age:22,
};
let copy_person = Object.assign({}, person) // here we copied `person` and store in `person_copy` using //Object.assign
copy_person.age = 21 // here we changed `age` value to `21` in `copy_person`
// using Object.assign
console.log(copy_person.age) // 21
console.log(person.age) //22
Using JSON.stringify() and JSON.parse() π
The JSON.stringify()
method takes in an object and creates a JSON string from it. The JSON.parse()
method parses a string and returns a JavaScript object.
// deep copy using The JSON.stringify() , JSON.parse() methods
const person = {
firstName:"Kushal",
lastName:"Das",
age:22,
};
// syntax:: objectIsNew = JSON.parse(JSON.stringify(objectIsOld));
let copy_person= JSON.parse(JSON.stringify(person)); // here we copied `person`
//and store in `person_copy`
copy_person.age = 21 // here we changed `age` value to `21` in `copy_person`
console.log(copy_person.age) // 21
console.log(person.age) //22
In the above examples ( Spread operator, Object.assign,JSON.stringify() , JSON.parse() ) we can say It makes a copy of all the members of person
, allocates different memory locations for copy_person
, and then assigns the copied members to copy_person
to achieve deep copy. In this way, if person
vanishes copy_person
is still valid in the memory. So here are the addresses of person
and copy_person
will be different i.e. they will be pointing to different memory location
.
Conclusion π₯β‘οΈ
A shallow copy of an object is a copy whose properties share the same references, if any of the fields of the object are references to other objects, just the reference addresses are copied which means only the memory address is copied.
A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. A deep copy is not going to change the original values if we make some changes in the clone object because they will be pointing to a different memory location.
We will use
deep copy
mostly in Non-Primitive Datatypes(Array , Object etc.) . Because if you don't want to change the original array and an object that casedeep copy
will help us.Here in this article, I mention about 3 ways to achieve
deep copy
In JS.
Thanks for reading all the way to the end! π
If you have any questions, please use the comments section π¬
Let's connect! Find me on the web π
If you have any Queries or Suggestions, feel free to reach out to me.
Happy Coding :)β€οΈ