1. Overview

In this blog, we will see different ways to clone or copy an object in NodeJs. which are also applicable in javascript and Algular as well. There are mainly two ways to close or copy the object one is deep copy and another is a shallow copy.

2. What are Deep copy and Shallow copy in Nodejs?

Whenever you clone some object it is either shallow copied or deep copied. So, what is deep copy and shallow copy? How it works?

  • Shallow copy: Shallow copy constructs a new object and copies top-level properties. Meaning if the object’s source property whose value isn’t an object, it will be copied without any reference. And whose value is an object, reference of that object will be copied. Any changes made in primitive data types of the original object won’t reflect in cloned one but changes of composite data types will. It is because of reference is being stored in the property.
  • Deep copy: Deep copy constructs a new object and copies each and every object. It doesn’t copy any reference of the object. Original and cloned both objects are independent from each other. Any changes made in the original will not reflect in the copied object and vice-versa.

3. Different ways to clone/copy an object

3.1 Directly assign one object to another

An easy way to clone an object is assigning one object to another. It works properly in the case of a primitive data type but not in composite data types.

  • With primitive data types
let a = 10;
let b = a;
console.log(a); //10
console.log(b); //10

b = 30;
console.log(a); //10
console.log(b); //30

In the above example, we assigned variable a to variable b. If we change the value of variable b, it won’t reflect back to a.

  • With composite data types
let a = { x: 10, y: 20 };
let b = a;
console.log(a); //{ x: 10, y: 20 }
console.log(b); //{ x: 10, y: 20 }

b.x = 30;
console.log(a); //{ x: 30, y: 20 }
console.log(b); //{ x: 30, y: 20 }

a.y = 40;
console.log(a); //{ x: 30, y: 40 }
console.log(b); //{ x: 30, y: 40 }

From the above example, you can see that, if we change the properties of any object it directly reflects to another one. So, we can say they are connected with each other through some reference.

3.2 Using Object.assign()

It will copy all properties from one or more source object to the target object and returns an object. The target object will be shallow copied. It takes one or more arguments. Two ways for using the method,

  1. Object.assign(targetObj) or Object.assign(targetObj , …sourceObj) : It returns a cloned object and append properties to existing targetObj also. If same key exist in both objects(targetObj , sourceObj), then sourceObj properties overwrite targetObj.
  2. Object.assign({}, …sourceObj) : It returns a cloned object. targetObj is empty so, it won’t append or overwrite any existing object. Later sourceObj properties overwrite Former sourceObj properties if objects contain the same key.
  • Using existing target object
let tagetObj1 = { x: 10, y: 20 };
let srcObj1 = { z: 30 };
let a = Object.assign(tagetObj1, srcObj1);
console.log(tagetObj1); //{ x: 10, y: 20, z: 30 }
console.log(srcObj1); //{ z: 30 }
console.log(a); //{ x: 10, y: 20, z: 30 }

srcObj1.z = 40;
console.log(tagetObj1); //{ x: 10, y: 20, z: 30 }
console.log(srcObj1); //{ z: 40 }
console.log(a); //{ x: 10, y: 20, z: 30 }

In the above example, a contains 3 properties like targetObj1. Changing any property of a or targetObj1 object directly reflects to another object. If we change srcObj1, it won’t reflect to a or targetObj1.

  • Using empty target object
let srcObj1 = { x: 10, y: 20 };
let srcObj2 = { z: 30 };
let a = Object.assign({}, srcObj1, srcObj2);
console.log(srcObj1); //{ x: 10, y: 20 }
console.log(srcObj2); //{ z: 30 }
console.log(a); //{ x: 10, y: 20, z: 30 }

srcObj2.z = 40;
console.log(srcObj1); //{ x: 10, y: 20 }
console.log(srcObj2); //{ z: 40 }
console.log(a); //{ x: 10, y: 20, z: 30 }

If we use an empty target object it won’t reflect to cloned object and any existing object as well.

  • Using the same key in 2 objects
let srcObj1 = { x: 10, y: 20 };
let srcObj2 = { x: 30 };
let a = Object.assign({}, srcObj1, srcObj2);
console.log(srcObj1); //{ x: 10, y: 20 }
console.log(srcObj2); //{ z: 30 }
console.log(a); //{ x: 30, y: 20 }

As we discussed, the same key overwrites the former object’s value. x of srcObj2 will overwrite x of srcObj1.

What if we use objects within source objects? Will it clone without any reference of source object the same as above? No, let’s see it with example.

  • An object within the source object
let srcObj1 = { x: 10, y: { z: 20 } };
let a = Object.assign({}, srcObj1);
console.log(srcObj1); //{ x: 10, y: { z: 20 } }
console.log(a); //{ x: 10, y: { z: 20 } }

srcObj1.y.z = 40;
console.log(srcObj1); //{ x: 10, y: { z: 40 } }
console.log(a); //{ x: 10, y: { z: 40 } }

You can see here, if we change source object it reflects to cloned object too. Is there any way to clone an object without any reference between source and target objects. Well yes..! we will see it later in this article.

3.3 Using spread(…) syntax

Another way to clone objects is to spread syntax. It will make a shallow copy of the source object just like Object.assign(). Changing the reference properties of the source object reflects to target object and vice-versa.

let srcObj1 = { x: 10, y: { z: 20 } };
let a = {...srcObj1 };
console.log(srcObj1); //{ x: 10, y: { z: 20 } }
console.log(a); //{ x: 10, y: { z: 20 } }

srcObj1.y.z = 40;
console.log(srcObj1); //{ x: 10, y: { z: 40 } }
console.log(a); //{ x: 10, y: { z: 40 } }

3.4 Deep clone using JSON

It clones object deeply and returns a deeply cloned object. If any property changes from source object it will not reflect to cloned object whether it is reference property or something else.

let srcObj1 = { x: 10, y: { z: 20 } };
let a = JSON.parse(JSON.stringify(srcObj1));
console.log(srcObj1); //{ x: 10, y: { z: 20 } }
console.log(a); //{ x: 10, y: { z: 20 } }

srcObj1.y.z = 40;
console.log(srcObj1); //{ x: 10, y: { z: 40 } }
console.log(a); //{ x: 10, y: { z: 20 } }

From the output, we can see by changing source object properties we can’t change the cloned objects.

4. Conclusion

In this article, we have seen different ways to copy an object. We learned about deep copy and shallow copy in Nodejs, how to use Object.assign(), spread syntax, and JSON methods to copy an object. That’s all we have learned about how you can clone/copy an object in javascript.

5. References

Was this post helpful?

Tags: ,

Leave a Reply

Your email address will not be published. Required fields are marked *