Shallow copy and Deep copy in JavaScript Introduction

Introduction

Copying is an important part of working with JavaScript, especially when working with objects and arrays. Understanding how to copy objects and arrays is an essential skill to ensure data consistency and safety in your application. In this article, we will learn about the difference between Shallow copy and Deep copy in JavaScript.

When working with JavaScript, we often want to create a copy of an object or array to work with data without affecting the original object. This is especially important when working with React or state management libraries, where data duplication is a common requirement.

In this article, we will learn about the different copy methods and how to use them to perform safe copying of objects and arrays in JavaScript.

Primitive data types

  • Boolean
  • Null
  • Undefined
  • String
  • Number
  • Symbol

Primitive data types are immutable  (they have no methods or properties that can change them).

Objects are all other JavaScript elements, such as literals, arrays, dates, and so on. and they are changeable . That means some methods can change them.

Example proving the value primitive is immutable:

 

When we try to change the first letter of the string from “B” to “C”, the variable name remains unchanged.

And an example demonstrating mutable objects:

Here we can see that changing the first element of the array results in changing the variable name.

To create a copy of the primitive variable, it’s very simple:

Creating a cloneName variable and giving it “=” with the variable name is enough to make a copy of it and won’t cause any problems since primitive variables are immutable. However, this method should be avoided for copying objects. Find out why.

From the above example, we can see that assigning one instance variable to another instance gives us a new variable with the same value. Do you think this is the right way?. But that’s not the case. And here’s why:

Oh, you see what’s not right? Applying the changes to the cloneUserObj variable transformed the original userObj variable as well, but how? To understand that, we first need to learn the fundamentals of computer science.

In programming languages there are two places to store data in computer memory: stack and heap.

  • Stack is a temporary storage for storing local primitive variables and references to objects.
  • Heap stores global variables. Object values stored on heap and stack contain only references to them (pointers).

As we learned at the beginning, primitive values are “passed by value”. According to the illustration above, we can see after creating two strings name and cloneName, string cloneName is assigned the value of string name to it, two distinct values, and there is no relation between them. Now those 2 variables are stored on stack.

Creating objects the same way results in the creation of two pointers (references) in the stack and only one value in the heap. When we create an instance variable, the memory stores the “address” in the actual location of the value, not the value itself. In this example we get two references pointing to the same value and this is why changing one of the objects will always change both objects. And this is also why we need duplicates.

We have two types of object copies in JavaScript, namely  shallow and deep. In short, Shallow copies are used for “flat” objects (which contain only primitive values) and Deep copies are used for “nested” objects (nested object, nested array).

To create a clone Shallow, we can use 1 of the following methods:

  • Spread syntax […] {…}
  • Object.assign()

And to create a  copy Deep  we can use:

  • JSON.parse(JSON.stringify())
  • Third party libraries like Lodash

Shallow clone

1. Spread syntax […] {…}

For example:

2. Object.assign()

For example:

As you can see, when we use the Shallow clone, if we change the clone variable, then the original variable will also change. Surely none of us want this, right? Let’s learn about Deep clones!

Deep clone

1. JSON.parse(JSON.stringify())

For example:

Oh, this seems like a simple and effective way to make a Deep clone, right? After changing the copy variable, the original variable remains unchanged. But let’s see what is the disadvantage of using this method

You see some params are gone without saying goodbye, so be careful what JavaScript gives us. That’s no joke for a professional JavaScript Developer.

2. Use _.cloneDeep of library Lodash

Using cloneDeep of the lodash library can handle the case when creating copies of nested objects, nested arrays like JSON.parse(JSON.stringify), and it also overcomes the disadvantage of not losing params like NaN, undefined, Infinity,…

Summary

In short, Shallow clones share references with source objects, they are more suitable for non-nested objects and are often used in programming with JavaScript. But if we have to deal with nested objects or we don’t know what value we get (e.g. from API), we should use Deep copies instead, because they don’t share any references to the original objects.

LongND1

Comments

Let’s make a great impact together

Be a part of BraveBits to unlock your full potential and be proud of the impact you make.