<?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>Forem: Daniel Ledvina</title>
    <description>The latest articles on Forem by Daniel Ledvina (@danielledvina).</description>
    <link>https://forem.com/danielledvina</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%2F3905819%2F068ad83f-50ee-4a1f-97e1-080435cfa875.jpeg</url>
      <title>Forem: Daniel Ledvina</title>
      <link>https://forem.com/danielledvina</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/danielledvina"/>
    <language>en</language>
    <item>
      <title>Closures made simple</title>
      <dc:creator>Daniel Ledvina</dc:creator>
      <pubDate>Fri, 01 May 2026 14:13:25 +0000</pubDate>
      <link>https://forem.com/danielledvina/closures-made-simple-1hb5</link>
      <guid>https://forem.com/danielledvina/closures-made-simple-1hb5</guid>
      <description>&lt;p&gt;⏱️ &lt;strong&gt;Reading time:&lt;/strong&gt; 5 minutes&lt;br&gt;
🎯 &lt;strong&gt;Difficulty:&lt;/strong&gt; Intermediate&lt;br&gt;
📂 &lt;strong&gt;Themes:&lt;/strong&gt; Lexical Scope, Encapsulation, SDK Patterns, Memory Management&lt;/p&gt;
&lt;h3&gt;
  
  
  What's inside?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Definition:&lt;/strong&gt; Demystifying "Lexical Environment" and the Backpack analogy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What are they for:&lt;/strong&gt; How closures provide Encapsulation and State Persistence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Comparison:&lt;/strong&gt; A side-by-side look at the "Global Mess" vs. the "Closure Approach."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production Use Case:&lt;/strong&gt; Building Secure API Clients to protect sensitive tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory leaks:&lt;/strong&gt; How to prevent Memory Leaks from timers and listeners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trade-offs:&lt;/strong&gt; Understanding memory overhead and debugging complexity.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;strong&gt;Closures&lt;/strong&gt; can be intimidating at first, but if you deep dive into the concept and its connections, it all makes sense right away. Let's get a grasp of what closures are, why they are essential, and how to manage them like a pro.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Definition
&lt;/h2&gt;

&lt;p&gt;According to &lt;strong&gt;MDN&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives a function access to its outer scope."&lt;br&gt;
— &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sounds a bit academic, right? Let's clarify that &lt;strong&gt;"Lexical"&lt;/strong&gt; part. In programming, "Lexical" simply means &lt;strong&gt;"where it is written in the code."&lt;/strong&gt; So, a closure is just a function that remembers the physical place where it was born.&lt;/p&gt;

&lt;p&gt;If I had to define it in short, I would say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"An intelligent function with private memory."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine a function that gets "born" inside another function. When the inner function leaves its "parent's house," it packs a &lt;strong&gt;backpack&lt;/strong&gt; full of all the variables it had access to at that moment. Even after the parent function has finished its execution, the inner function carries that backpack wherever it goes.&lt;/p&gt;
&lt;h2&gt;
  
  
  What are they for?
&lt;/h2&gt;

&lt;p&gt;The primary purpose of a closure is &lt;strong&gt;Encapsulation&lt;/strong&gt;. It allows you to create private variables that cannot be accessed or modified from the outside world. It also enables &lt;strong&gt;State Persistence&lt;/strong&gt;, meaning a function can "remember" data between executions without relying on messy global variables.&lt;/p&gt;

&lt;p&gt;In essence, closures allow you to bundle "data" and "logic" together in a tiny, self-contained package.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 The React Connection:&lt;/strong&gt; If you've ever used &lt;strong&gt;React Hooks&lt;/strong&gt; (like &lt;code&gt;useState&lt;/code&gt;), you are using closures! React uses a closure to "remember" your state value between re-renders. Even though your component function finishes running completely, the state stays alive in a "backpack" managed by React.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  See it in action
&lt;/h2&gt;

&lt;p&gt;To truly appreciate closures, look at how we manage state without them.&lt;/p&gt;
&lt;h3&gt;
  
  
  ❌ Before: The "Global Mess" approach
&lt;/h3&gt;

&lt;p&gt;If you want a counter to remember its value, you might use a global variable. But anyone else's code can accidentally overwrite it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Publicly accessible - DANGEROUS&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Current count:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Oops, I broke it&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Someone else's code ruins your logic&lt;/span&gt;
&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// NaN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this approach is problematic:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚨 &lt;strong&gt;Vulnerability:&lt;/strong&gt; Because the &lt;code&gt;count&lt;/code&gt; variable is public, any other part of your application can accidentally or intentionally overwrite it.&lt;/li&gt;
&lt;li&gt;🏚️ &lt;strong&gt;Fragility:&lt;/strong&gt; Your logic is brittle. A single line of "rogue" code—such as assigning a string to a variable expected to be a number—permanently breaks the functionality.&lt;/li&gt;
&lt;li&gt;☁️ &lt;strong&gt;Pollution:&lt;/strong&gt; As applications grow, global variables lead to &lt;strong&gt;"Global Scope Pollution,"&lt;/strong&gt; making it nearly impossible to track which piece of code is responsible for changing a specific value.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ After: The "Closure" approach
&lt;/h3&gt;

&lt;p&gt;With a closure, the &lt;code&gt;count&lt;/code&gt; variable is "closed" inside the scope. It is safe from outside interference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Private memory - SAFE&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Current count:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createCounter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;myCounter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nf"&gt;myCounter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="c1"&gt;// 'count' cannot be accessed or ruined from here!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this approach wins:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔒 &lt;strong&gt;Private Memory:&lt;/strong&gt; The &lt;code&gt;count&lt;/code&gt; variable lives only inside the &lt;code&gt;createCounter&lt;/code&gt; scope. Once the function is executed, the variable "disappears" from the global perspective.&lt;/li&gt;
&lt;li&gt;🔑 &lt;strong&gt;Exclusive Access:&lt;/strong&gt; The only way to interact with the data is through the returned function. This function "remembers" its birthplace and carries that memory in its "backpack" wherever it goes.&lt;/li&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Security &amp;amp; Integrity:&lt;/strong&gt; No outside script can access or corrupt the &lt;code&gt;count&lt;/code&gt; variable. You have created a secure "black box" where the data and the logic are bundled together.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Case: Secure API Clients
&lt;/h2&gt;

&lt;p&gt;In production environments (like building a Stripe or Firebase SDK), you often need to handle sensitive data like Access Tokens. Storing these in &lt;code&gt;localStorage&lt;/code&gt; makes them vulnerable to XSS attacks.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;"Really Real-World"&lt;/strong&gt; solution? Use a closure to create a private API client where the sensitive state is physically inaccessible from the global scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is how modern secure SDKs often handle internal state&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createApiClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// SENSITIVE DATA: This lives only in the closure's "backpack"&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Fetching from &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// The token is used internally here, but never exposed to the outside&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;updateToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Update the private memory safely&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createApiClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.mybank.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your_initial_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Works perfectly:&lt;/span&gt;
&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/balance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// SECURE: No rogue script can do this:&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; By using a closure, you've created a hard boundary. The only way to use that token is through the approved &lt;code&gt;getData&lt;/code&gt; method. This is a standard pattern for building secure, encapsulated JavaScript libraries.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Catch: Memory Leaks
&lt;/h2&gt;

&lt;p&gt;A closure is like a "living connection" to its variables. Memory leaks happen when you leave these connections active after you no longer need them. &lt;strong&gt;"Similar to subscriptions, you need to sort of 'unsubscribe' from the closure to ensure that memory leakage is not present."&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The "Zombie" Timer
&lt;/h3&gt;

&lt;p&gt;When you use a closure inside a &lt;code&gt;setInterval&lt;/code&gt;, the system keeps that "backpack" alive so it can run every second.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;startHeartbeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Heartbeat for:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;heartbeat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;startHeartbeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SensitiveData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// CLEANUP:&lt;/span&gt;
&lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;heartbeat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;heartbeat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. The "Sticky" Event Listener
&lt;/h3&gt;

&lt;p&gt;Global objects like &lt;code&gt;window&lt;/code&gt; or &lt;code&gt;document&lt;/code&gt; stay alive as long as the app is running. If you "glue" a closure to them, it will stay in memory forever unless you manually unstick it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;trackScroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;componentName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Scrolling in &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;componentName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Return a function to "unstick" the listener later&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stopTracking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;trackScroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// When leaving the page:&lt;/span&gt;
&lt;span class="nf"&gt;stopTracking&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. The "Forgotten" Global Reference
&lt;/h3&gt;

&lt;p&gt;If you store a closure in a variable that lives for a long time, the memory stays locked. Simply tell the Garbage Collector: &lt;em&gt;"I am done with this."&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;secureVault&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSecureVault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ... later ...&lt;/span&gt;
&lt;span class="nx"&gt;secureVault&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Final thought:&lt;/strong&gt; A closure isn't a memory leak by itself. A leak only happens when you &lt;strong&gt;forget to stop&lt;/strong&gt; the process (Timer, Listener, or Reference) that keeps the closure alive.&lt;/p&gt;




&lt;h2&gt;
  
  
  Trade-offs
&lt;/h2&gt;

&lt;p&gt;While closures are powerful, they aren't "free":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory Overhead:&lt;/strong&gt; Variables in a closure's "backpack" are not garbage collected while the function exists. In high-performance apps, thousands of closures can cause "Memory Bloat."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution Speed:&lt;/strong&gt; Creating a function inside another function is slightly slower than defining a function on a prototype.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging Complexity:&lt;/strong&gt; Inspecting private state is harder. You can't just &lt;code&gt;console.log(client)&lt;/code&gt; to see the token; you have to use breakpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testability:&lt;/strong&gt; If logic is too "private," it can be harder to unit test specific internal states without exposing them.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Closures allow you to write functions that are smart, private, and independent. They are the engine behind &lt;strong&gt;React Hooks&lt;/strong&gt;, &lt;strong&gt;Secure SDKs&lt;/strong&gt;, and elegant &lt;strong&gt;Encapsulation&lt;/strong&gt;. Once you understand that a closure is just a function with a memory, you are good to go.&lt;/p&gt;




&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;The views expressed in this post are based on my personal learning journey. While closures are a standard feature, always ensure you follow your team's specific architectural patterns and performance guidelines to avoid unintended side effects.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>closure</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
