Copy Objects in JS : Shallow Copy vs Deep copy
Tags: javascript, beginners, programming, react
Published: 2023-03-15 20:15:12

**4-ways to copy Object in javascript:**

1) Use the spread (...) syntax
2) Use the Object.assign() method
3) Use the JSON.stringify() and JSON.parse() methods
4) Lodash To Deep Copy

## Shallow copy vs. deep copy

In JavaScript, you use variables to store values that can be primitive or references. When you make a copy of a value stored in a variable, you create a new variable with the same value. For a primitive value, you just simply use a simple assignment:

`let counter = 1;
let copiedCounter = counter;
Code language: JavaScript (javascript)
/**
And when you change the value of the copied variable, the value of the original remains the same.
*/

copiedCounter = 2;
console.log(counter);`

//output
1

A deep copying means that value of the new variable is disconnected from the original variable while a shallow copy means that some values are still connected to the original variable.

**Shallow copy example:**

Consider the following example:

`let person = {
    firstName: 'John',
    lastName: 'Doe',
    address: {
        street: 'North 1st street',
        city: 'San Jose',
        state: 'CA',
        country: 'USA'
    }
};


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

copiedPerson.firstName = 'Jane'; // disconnected

copiedPerson.address.street = 'Amphitheatre Parkway'; // connected
copiedPerson.address.city = 'Mountain View'; // connected

console.log(copiedPerson);
`
In this example:

1)First, create a new object named person.
2)Second, clone the person object using the Object.assign() method.
3)Third, change the first name and address information of the copiedPerson object.

Here is the output:

`{
    firstName: 'Jane',
    lastName: 'Doe',
    address: {
        street: 'Amphitheatre Parkway',
        city: 'Mountain View',
        state: 'CA',
        country: 'USA'
    }
}`

However, when you show the values of the person object, you will find that the address information changed but the first name:

`console.log(person);
Code language: JavaScript (javascript)
Output:

{
    firstName: 'John',
    lastName: 'Doe',
    address: {
        street: 'Amphitheatre Parkway',
        city: 'Mountain View',
        state: 'CA',
        country: 'USA'
    }
}`

The reason is that the address is reference value while the first name is a primitive value. Both person and copiedPerson references different objects but these objects reference the same address objects.

**Deep copy example**

The following snippet replaces the Object.assign() method by the JSON methods to carry a deep copy the person object:

`let person = {
    firstName: 'John',
    lastName: 'Doe',
    address: {
        street: 'North 1st street',
        city: 'San Jose',
        state: 'CA',
        country: 'USA'
    }
};


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

copiedPerson.firstName = 'Jane'; // disconnected

copiedPerson.address.street = 'Amphitheatre Parkway';
copiedPerson.address.city = 'Mountain View';

console.log(person);

Output

{
    firstName: 'John',
    lastName: 'Doe',
    address: {
        street: 'North 1st street',
        city: 'San Jose',
        state: 'CA',
        country: 'USA'
    }
}`

In this example, all values in the copiedPerson object are disconnected from the original person object.


**Deep Cloning for non-serializable:**

But if the object is very large and contains certain non-serializable properties then there is a risk of data loss. Especially if an object contains methods then JSON.stringify() will fail as methods are non-serializable. 

Lodash To Deep Copy: Lodash is a JavaScript library that provides multiple utility functions and one of the most commonly used functions of the Lodash library is the cloneDeep() method. This method helps in the deep cloning of an object and also clones the non-serializable properties which were a limitation in the JSON.stringify() approach.


`
const lodash = require('lodash');
var employee = {
    eid: "E102",
    ename: "Jack",
    eaddress: "New York",
    salary: 50000,
    details: function () {
        return "Employee Name: "
            + this.ename + "-->Salary: "
            + this.salary;
    }
}
 
var deepCopy = lodash.cloneDeep(employee);
console.log("Original Employee Object");
console.log(employee);
console.log("Deep Copied Employee Object");
console.log(deepCopy);
deepCopy.eid = "E103";
deepCopy.ename = "Beck";
deepCopy.details = function () {
    return "Employee ID: " + this.eid
        + "-->Salary: " + this.salary;
}
console.log("----------After Modification----------");
console.log("Original Employee Object");
console.log(employee);
console.log("Deep Copied Employee Object");
console.log(deepCopy);
console.log(employee.details());
console.log(deepCopy.details());`