Copying Objects

There are two types of copy javascript perform shallow copy and deep copy.

  • Shallow Copy - copied data still points to the orignal data and changes in copied data affects orignal data.
  • Deep Copy - copied data does not point to the orignal data both have different references.

We can use === to compare if both point to the same reference or not.

Ways to copy

  • Using assignment operator = (performs shallow copy)
const person = {
    name: 'bippan', address: {
        country: 'India',
        state: 'Punjab'
    }
}

const copyPerson = person

copyPerson.name = 'sourav'

console.log(person === copyPerson)  // true

console.log({ person, copyPerson })
/* { person:
   { name: 'sourav',
     address: { country: 'India', state: 'Punjab' } },
  copyPerson:
   { name: 'sourav',
     address: { country: 'India', state: 'Punjab' } } } */

When copyPerson.name is changed to 'sourav' person.name also changes, so any changes on the copyPerson will affect the person object.

  • Copy array using spread operator ...
const copyPerson = { ...person }

console.log(person === copyPerson) // false

copyPerson.name = 'sourav'

console.log({ copyPerson, person })
/*
{ copyPerson:
   { name: 'sourav',
     address: { country: 'India', state: 'Punjab' } },
  person:
   { name: 'bippan',
     address: { country: 'India', state: 'Punjab' } } }
*/

copyPerson.address.state = 'Haryana'

console.log(person.address === copyPerson.address) // true

console.log({ copyPerson, person })
/*
{ copyPerson:
   { name: 'sourav',
     address: { country: 'India', state: 'Haryana' } },
  person:
   { name: 'bippan',
     address: { country: 'India', state: 'Haryana' } } }
*/

In this example you can see person === copyPerson prints false, so when we change copyPerson.name it does not affects the person.name.

But person.address === copyPerson.address prints true, means copyPerson holds same reference as the orignal object for the nested objects.

  • Copy using JSON.parse() and JSON.stringify() (performs deep copy)
const copyPerson = JSON.parse(JSON.stringify(person))

console.log(person === copyPerson)  // false

copyPerson.name = 'sourav'

console.log({ copyPerson, person })
/*
{ copyPerson: 
   { name: 'sourav',
     address: { country: 'India', state: 'Punjab' } },
  person: 
   { name: 'bippan',
     address: { country: 'India', state: 'Punjab' } } }
*/

copyPerson.address.state = 'Haryana'

console.log(person.address === copyPerson.address) // false

console.log({ copyPerson, person })
/*
{ copyPerson: 
   { name: 'sourav',
     address: { country: 'India', state: 'Haryana' } },
  person: 
   { name: 'bippan',
     address: { country: 'India', state: 'Punjab' } } }
*/

Changing the value of copyPerson does not change the person value, in this case copyPeron does not share any reference of the person object.

person === copyPerson prints false

person.address === copyPerson.address prints false