<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Moiz Ali</title>
    <description>The latest articles on DEV Community by Moiz Ali (@moizali).</description>
    <link>https://dev.to/moizali</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3010047%2F683fc04b-12bf-4d7a-9fc4-2b28af348b0b.jpg</url>
      <title>DEV Community: Moiz Ali</title>
      <link>https://dev.to/moizali</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moizali"/>
    <language>en</language>
    <item>
      <title>JavaScript Memory Model: Understanding Data Types, References, and Garbage Collection</title>
      <dc:creator>Moiz Ali</dc:creator>
      <pubDate>Thu, 03 Apr 2025 03:03:25 +0000</pubDate>
      <link>https://dev.to/moizali/javascript-memory-model-understanding-data-types-references-and-garbage-collection-mgc</link>
      <guid>https://dev.to/moizali/javascript-memory-model-understanding-data-types-references-and-garbage-collection-mgc</guid>
      <description>&lt;p&gt;JavaScript's handling of memory and data types is often misunderstood, leading to bugs and performance issues. This article takes an investigative approach to examine how JavaScript manages memory through practical code examples.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1: The Two Worlds of JavaScript Data Types
&lt;/h2&gt;

&lt;p&gt;Primitive vs Reference Types: A Fundamental Distinction&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Primitive example
let a = 5;
let b = a;
a = 10;
console.log(a); // 10
console.log(b); // 5

// Reference example
let x = [1, 2, 3];
let y = x;
x.push(4);
console.log(x); // [1, 2, 3, 4]
console.log(y); // [1, 2, 3, 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Investigation #1:&lt;/strong&gt; Let's examine what's happening in memory:&lt;/p&gt;

&lt;p&gt;Primitive values are stored directly in the variable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When b = a happens, the value 5 is copied from a to b&lt;/li&gt;
&lt;li&gt;When a changes to 10, b remains unchanged&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reference values store a pointer to the data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When y = x happens, both variables reference the same array&lt;/li&gt;
&lt;li&gt;When we modify the array through x, y sees those changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Definitive List of Data Types
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Primitive Types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;String&lt;/li&gt;
&lt;li&gt;Number&lt;/li&gt;
&lt;li&gt;Boolean&lt;/li&gt;
&lt;li&gt;Undefined&lt;/li&gt;
&lt;li&gt;Null&lt;/li&gt;
&lt;li&gt;Symbol&lt;/li&gt;
&lt;li&gt;BigInt&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Reference Types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object (including Arrays, Functions, Dates, RegExps, Maps, Sets, etc.)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 2: Diving into Reference Memory Model
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Behind-the-Scenes Investigation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's probe deeper with some experiments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Experiment 1: Objects and equality
let obj1 = { name: "Alice" };
let obj2 = { name: "Alice" };
let obj3 = obj1;

console.log(obj1 === obj2); // false
console.log(obj1 === obj3); // true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Investigation #2:&lt;/strong&gt; Why do identical-looking objects compare as not equal?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;obj1 and obj2 point to different memory locations&lt;/li&gt;
&lt;li&gt;obj1 and obj3 point to the same memory location
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Experiment 2: Modifying through references
let person = { name: "Bob", age: 30 };
let jobProfile = { person: person, title: "Developer" };

person.age = 31;
console.log(jobProfile.person.age); // 31
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Investigation #3:&lt;/strong&gt; Nested objects share references&lt;/p&gt;

&lt;p&gt;Changing person affects what you see through jobProfile.person&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visualizing Memory References&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Reassignment vs. modification
let arr1 = [1, 2, 3];
let arr2 = arr1;

// Modification (affects both references)
arr1.push(4);
console.log("After modification:");
console.log(arr1); // [1, 2, 3, 4]
console.log(arr2); // [1, 2, 3, 4]

// Reassignment (only affects one variable)
arr1 = [5, 6, 7];
console.log("After reassignment:");
console.log(arr1); // [5, 6, 7]
console.log(arr2); // [1, 2, 3, 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Investigation #4:&lt;/strong&gt; Two different operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modification: Changes the data both variables point to&lt;/li&gt;
&lt;li&gt;Reassignment: Makes a variable point to new data&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 3: Garbage Collection in Practice
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;When Does Memory Get Freed?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Creating potentially unused objects
function createObjects() {
  let tempArray = new Array(1000).fill("data");

  // This object becomes unreachable after the function returns
  let unretainedObject = { huge: new Array(10000).fill("more data") };

  // This object will be returned and retained
  let retainedObject = { name: "I survive" };

  return retainedObject;
}

let survivor = createObjects();
// When does unretainedObject get garbage collected?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Investigation #5:&lt;/strong&gt; Tracing object lifecycles&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unretainedObject becomes eligible for GC when createObjects() returns&lt;/li&gt;
&lt;li&gt;retainedObject remains in memory because it's assigned to survivor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Memory Leaks: When References Persist&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Potential memory leak through closures
function setupHandler() {
  let largeData = new Array(10000).fill("lots of data");

  return function() {
    // This closure maintains a reference to largeData
    console.log("Handler using", largeData.length, "items");
  };
}

let handler = setupHandler();
// largeData remains in memory as long as handler exists
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Investigation #6:&lt;/strong&gt; Unintended retention&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Even though we never directly access largeData again, it stays in memory&lt;/li&gt;
&lt;li&gt;The closure in the returned function maintains a reference&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 4: Practical Implications
&lt;/h2&gt;

&lt;p&gt;Copying Objects: Shallow vs. Deep Copy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Shallow copy
let original = { name: "Original", details: { id: 123 } };
let shallowCopy = { ...original }; // or Object.assign({}, original)

shallowCopy.name = "Changed";
shallowCopy.details.id = 456;

console.log(original.name);       // "Original" (primitive value was copied)
console.log(original.details.id); // 456 (reference value was shared)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Investigation #7:&lt;/strong&gt; The limits of spread operator and Object.assign&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They only create a shallow copy&lt;/li&gt;
&lt;li&gt;Nested objects are still shared references&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Performance Considerations&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Creating many short-lived objects
function processData(items) {
  let results = [];

  for (let i = 0; i &amp;lt; items.length; i++) {
    // Each iteration creates new temporary objects
    let temp = {
      processed: items[i] * 2,
      original: items[i]
    };
    results.push(temp.processed);
  }

  return results;
}

const data = new Array(10000).fill(0).map((_, i) =&amp;gt; i);
console.time("processing");
processData(data);
console.timeEnd("processing");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Investigation #8:&lt;/strong&gt; Object creation overhead&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating many small objects can impact performance&lt;/li&gt;
&lt;li&gt;Garbage collector has to work harder to clean up&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Understanding JavaScript's memory model isn't just academic—it impacts how we write code daily. By grasping the difference between primitives and references, you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Avoid unintended side effects when passing objects to functions&lt;/li&gt;
&lt;li&gt;Make informed decisions about copying data&lt;/li&gt;
&lt;li&gt;Prevent memory leaks by understanding object lifecycle&lt;/li&gt;
&lt;li&gt;Write more performant code by being mindful of object creation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember: In JavaScript, we don't just work with values—we work with references to values. Keeping this mental model clear will make you a more effective JavaScript developer.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>datatypes</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
