Understanding JavaScript Objects, Memory Management, and Deep Copying: A Complete Guide

In JavaScript, objects are one of the most powerful data structures used to represent real-world entities. But behind the scenes, there's a whole world of memory management concepts like stack, heap, garbage collection, and memory leaks. This article breaks down everything you need to know—from the basics of objects to deep-copying techniques and memory internals in JS.
NOTE: This Article is Inspired by Hitesh Choudhary’s and Piyush Garg’s Web Cohort 1.0
What Are Data Structures?
Data structure refers to how you store your data in memory.
Examples:
Stack
Queue
Key-Value Pairs
Two Main Types of Data Structures:
Primitive Data Structures
fundamental and immutable(Can’t change the value once created)
Example: string, number, boolean,
Non-Primitive Data Structures
Custom implemented by the developer
Examples: Stack, Linked List, Graph
JavaScript Objects: The Real-World Representation
While arrays store data sequentially, objects store data in key-value pairs.
You use curly braces {}
to define an object. Objects can also contain:
Arrays
Functions (called methods)
Nested objects
Example:
const person = {
firstname: 'John',
lastname: 'Wick',
hobbies: ['reading', 'traveling'],
ismarried: false,
getfullname: function () {
return "John Wick";
},
address: {
house_no: 1,
street: 3,
countrycode: "US",
state: "NY",
pincode: 123456
}
};
Use Case of Objects
Objects help group related data using keys. This concept is similar to SQL tables with key-value records.
Real World Analogy:
Let’s say we want to represent a remote in code:
const remote = {
color: "black",
brand: "Samsung",
dimensions: {
height: 10,
width: 5,
depth: 1
},
turnoff: function () {
console.log("turning off the TV");
},
volumeup: function () {
console.log("increasing the volume");
}
}
How to Copy Objects in JavaScript (With Different Memory Locations)
Way 1: Using Spread Operator
let p1 = {
fname: 'John',
lname: 'Wick',
address: {
house_no: 1,
street: 3,
countrycode: "IN",
state: "GJ",
pincode: 360005
}
};
let p2 = {
...p1
};
// ... = Spread operator
// spread operator generates shalllow copy of object
// (just copy the outer elements not nested objects e.g. address)
Problem:
This is a shallow copy. Nested objects are not duplicated; they still refer to the same memory.
Way 2: Deep Copy Using Serialization and Deserialization
let p1 = {
fname: 'John',
lname: 'Wick',
address: {
house_no: 1,
street: 3,
countrycode: "IN",
state: "GJ",
pincode: 360005
}
};
// Serialization:
// conversion of object to string, then stored it in p1_string
const p1_string = JSON.stringify(p1);
// Deserialization:
// conversion of string to object, then stored it in p2
let p2 = JSON.parse(p1_string);
This method ensures that nested objects are copied too, giving p2
a completely different memory reference.
How Objects Are Stored in Memory
There are two types of memory in any programming language:
Stack Memory:
Stores primitive variables like strings, numbers, booleans.
Fixed size.
Fast read/write.
Automatically removed after execution.
const fname = "Spongebob";
const lname = "Squidward";
These will be stored in stack memory.
Heap Memory:
Stores non-primitive types like arrays, objects, graphs, trees.
Dynamically allocated.
Slower due to pointer lookups.
Example:
const p1 = {
fname: "Piyush",
lname: "Garg"
};
This object is stored in heap memory, but p1
(the reference/pointer) is stored in stack.
Let’s say heap memory address is 0x1
, then:
p1
=0x1
(in stack)Object
{ fname, lname }
= stored at0x1
(in heap)
When we do:
let p2 = p1;
Now:
p2
=0x1
Both
p1
andp2
point to the same object.
Changes in p2
reflect in p1
.
Garbage Collection in JavaScript
const p1 = {
fname: "Piyush",
lname: "Garg"
};
let p2 = p1;
If both p1
and p2
go out of scope (removed from stack), the object in heap (0x1
) has no references.
JS Garbage Collector:
Automatically detects unreferenced heap data.
Frees memory.
In languages like C/C++:
You must manually:
Free heap memory
Remove pointers from stack
Memory Leak Explained
const p1 = { fname: "Piyush", lname: "Garg" };
let p2 = p1;
Now imagine, 2 developers works together on a project:
Dev1 uses
p1
Dev2 uses
p2
If Dev2 deletes p2
and the heap memory it points to (0x1
), then p1
becomes a dangling pointer.
Now:
p1
points to memory with someone else’s data.Any changes via
p1
will corrupt that data.
This is called a Memory Leak
In languages without a Garbage Collector, developers must manually check if any pointer still exists before deleting memory.
In JavaScript, Garbage Collector handles it for you, ensuring safety.
Summary of Memory Behavior
Data Type | Stored In | Notes |
Primitive types | Stack | Fixed size |
Non-primitive | Heap | Dynamic memory |
Pointers | Stack | Point to heap |
Final Thoughts
Understanding how JavaScript handles objects and memory is crucial for writing efficient, bug-free code, especially as your apps scale. With these fundamentals, you're better equipped to handle performance, cloning issues, and even deep system-level questions in interviews or real-world projects.
Subscribe to my newsletter
Read articles from Dharmik B. directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
