Copy Objects in Javascript

Copy Objects in Javascript

Table of Contents

Understanding JavaScript Object Mechanisms

  • DeepCopy VS ShallowCopy

    • Shallow Copy

    • Deep Copy

  • Methods to Copy Objects

    • Shallow Copy Using the Spread Operator (...)

    • Shallow Copy Using Object.assign()

    • Deep Copy Using JSON.parse(JSON.stringify(obj))

    • Deep Copy Using a Custom Function

    • Deep Copy Using Lodash's _.cloneDeep() Method

    • Using JavaScript's Native structuredClone() Method

Note: In javascript everything (wwell almost everything! ) is an object.

I am talking about copying an object that includes, strings, arrays, objects, functions, and other data types except null and undefined.

But why do we need to copy an object in Javascript, one may ask?

let obj1 = {
    a : "1234"
}

let obj2 = obj1 

obj1.a // "1234"
obj2.a // "1234"

Here, we already had an obj1 which has a property a we want to have this exact value to be stored in another object say obj2. Now the simplest thing to do is to an assignment operation obj2 = obj1 now obj2 also has a a property in it.

but, let's change the value obj1.a to something else and see how it affects the obj2.

consider :

let obj1 = {
    a : "1234"
}

let obj2 = obj1 

obj1.a // "1234"
obj2.a // "1234"

obj1.a = "something else"

Actual behavior

obj1.a // "something else"
obje2.a // "something else"

That's might seem like a weird side-effect to you but it just means you don't yet understand how javascript stores the values in Input. Let's understand it in the further article.

Understanding Javascript Object Mechanisms

To understand the above behavior you need to understand how Javascript Objects work and how the values are stored in the Javascript. Well, Javascript does not store the exact value but instead, it contains a reference to the memory where the value is stored.

Does it make sense? If not below illustration may help you to understand better.

As in Above Diagram you can see in MyObject.a and MyObject.b have a value stored where values are Object1 and arr1 . But In actuality, the value is not stored instead the reference to memory is saved.

So in our previous example when we changed the value of obj1.a to something else the value is changed but obj2 still referred to obj1 hence it changes with it.

DeepCopy VS ShallowCopy

Let's understand these two ways to fully understand how we can finally be able to understand how to copy an object in Javascript.

  1. Shallow Copy

    A shallow copy of an object only creates a new reference to the same object, not a completely new object. This means that if you modify a property of the shallow copy, the original object will also be modified because both objects reference the same underlying object.

    Example:

let originalObj = {a: 1, b: {c: 2}};
let shallowCopy = Object.assign({}, originalObj);
console.log(originalObj.b === shallowCopy.b) // outputs: true
shallowCopy.b.c = 3;
console.log(originalObj.b.c) // outputs: 3
  1. Deep Copy

    A deep copy, on the other hand, is a copy of an object that is completely independent of the original object. Changes made to the properties of the deep copy will not affect the properties of the original object.

    Example:

let originalObj = {a: 1, b: {c: 2}};
let deepCopy = JSON.parse(JSON.stringify(originalObj));
console.log(originalObj.b === deepCopy.b) // outputs: false
deepCopy.b.c = 3;
console.log(originalObj.b.c) // outputs: 2

Note: Using the above method may cause some problems with Date Object as it's a Javascript Object.

Hence while deep copying it is advised to use the popular OSS library's lodash _.cloneDeep() method or write a program that recursively does copy in each level of a nested Javascript Object.

Methods to copy Objects.

In JavaScript, there are several methods to copy an object:

  1. Shallow copy using the spread operator ...

goCopy codeconst original = { a: 1, b: 2 };
const copy = { ...original };

Pros:

  • Easy to use

  • Works with all enumerable properties, including arrays and objects

Cons:

  • Only creates a shallow copy, meaning that any nested objects or arrays are still referenced and not copied.
  1. Shallow copy using Object.assign()

javascriptCopy codeconst original = { a: 1, b: 2 };
const copy = Object.assign({}, original);

Pros:

  • Easy to use

  • Works with all enumerable properties, including arrays and objects

Cons:

  • Only creates a shallow copy, meaning that any nested objects or arrays are still referenced and not copied
  1. Deep copy using JSON.parse(JSON.stringify(obj))

javascriptCopy codeconst original = { a: 1, b: 2, c: { d: 3 } };
const copy = JSON.parse(JSON.stringify(original));

Pros:

  • Easy to use

  • Creates a deep copy, meaning that any nested objects or arrays are also copied

Cons:

  • Will not work for objects with circular references or for non-JSON data types (e.g. functions, symbol properties)

  • Can be slow for large objects

  1. Deep copy using a custom function

scssCopy codefunction deepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  let copy;
  if (Array.isArray(obj)) {
    copy = [];
    for (let i = 0; i < obj.length; i++) {
      copy[i] = deepCopy(obj[i]);
    }
  } else {
    copy = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        copy[key] = deepCopy(obj[key]);
      }
    }
  }

  return copy;
}

Pros:

  • Creates a deep copy, meaning that any nested objects or arrays are also copied

  • Can handle objects with circular references or non-JSON data types

Cons:

  • More complicated to implement

  • Slower for large objects compared to JSON.parse(JSON.stringify(obj))

  1. Deep copy using Lodash's _.cloneDeep() method

javascriptCopy codeconst _ = require('lodash');
const original = { a: 1, b: 2, c: { d: 3 } };
const copy = _.cloneDeep(original);

Pros:

  • Easy to use

  • Creates a deep copy, meaning that any nested objects or arrays are also copied

  • Can handle objects with circular references or non-JSON data types

  • Generally faster for large objects compared to a custom deep copy function

Cons:

  • Requires the Lodash library to be installed

  • Adds extra size to your codebase if you only need this single function.

  1. Using Javascript's Native structuredClone() method

// Create an object with a value and a circular reference to itself.
const original = { name: "MDN" };
original.itself = original;

// Clone it
const clone = structuredClone(original);

console.assert(clone !== original); // the objects are not the same (not same identity)
console.assert(clone.name === "MDN"); // they do have the same values
console.assert(clone.itself === clone); // and the circular reference is preserved

Pros :

  • Javascript Native Support hence no library is required.

Cons:

  • This method is not a part of ECMAScript it was added to the platform-specific parts.

Conclusion

In conclusion, copying an object in JavaScript can be a complex task due to its nature of storing references instead of actual values. Shallow copy is created by methods such as spread operator (...), Object.assign(), and only creates a new reference to the same object, modifying the property in the shallow copy will affect the original object. On the other hand, a deep copy creates a completely independent copy of an object, and changes made to the properties of the deep copy will not affect the properties of the original object. It is advised to use popular libraries like lodash to create a deep copy or to write a program that recursively copies each level of a nested Javascript object.

![](https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=abhishekdandriyal&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff align="left")