<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged lexicalscope</title>
<link>https://coderlegion.com/tag/lexicalscope</link>
<description>Powered by Question2Answer</description>
<item>
<title>JavaScript Lexical Scope, Lexical Environment, Scope Chain &amp; Closure — Explained Like the JS Engine</title>
<link>https://coderlegion.com/22067/javascript-lexical-scope-lexical-environment-scope-chain-closure-explained-like-engine</link>
<description>&lt;p&gt;Most developers memorize the definitions of &lt;strong&gt;Lexical Scope&lt;/strong&gt;, &lt;strong&gt;Lexical Environment&lt;/strong&gt;, &lt;strong&gt;Scope Chain&lt;/strong&gt;, and &lt;strong&gt;Closure&lt;/strong&gt; without understanding what actually happens inside the JavaScript engine.&lt;/p&gt;
&lt;p&gt;In this article, we'll build these concepts step by step and understand them from the engine's perspective.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;What Does &quot;Lexical&quot; Mean?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lexical&lt;/strong&gt; means:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;&quot;Based on where things are written in the source code.&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;JavaScript determines variable access by looking at the &lt;strong&gt;physical location&lt;/strong&gt; of functions in your code—not where they are called.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;1-lexical-scope&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/@gauravsingh7x/javascript-lexical-scope-lexical-environment-scope-chain-closure-explained-like-the-js-engine-dc090baa273a&quot;&gt;1. Lexical Scope&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A function can access:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Its own variables&lt;/li&gt;
&lt;li&gt;Variables from its outer scope&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The scope is determined by &lt;strong&gt;where a function is defined&lt;/strong&gt;, &lt;strong&gt;not where it is executed&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;let dynamicVar = &quot;I'm Global&quot;;

function checkScope() {
  console.log(dynamicVar);
}

function anotherFunction() {
  let dynamicVar = &quot;I'm Local&quot;;
  checkScope(); // Function is called here
}

anotherFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;output&quot;&gt;Output&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;I'm Global
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;why-&quot;&gt;Why?&lt;/h3&gt;
&lt;p&gt;Before execution begins, JavaScript analyzes the source code and decides which variables every function can access.&lt;/p&gt;
&lt;p&gt;This rule is called &lt;strong&gt;Lexical (Static) Scope&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Although &lt;code&gt;checkScope()&lt;/code&gt; is called inside &lt;code&gt;anotherFunction()&lt;/code&gt;, it was &lt;strong&gt;defined in the global scope&lt;/strong&gt;, so it only has access to the global &lt;code&gt;dynamicVar&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-if-javascript-used-dynamic-scope-&quot;&gt;What If JavaScript Used Dynamic Scope?&lt;/h3&gt;
&lt;p&gt;If JavaScript used &lt;strong&gt;Dynamic Scope&lt;/strong&gt; (which depends on where a function is called), the output would be:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;I'm Local
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But JavaScript &lt;strong&gt;doesn't&lt;/strong&gt; work this way.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;lexical-scope-search-path&quot;&gt;Lexical Scope Search Path&lt;/h3&gt;
&lt;p&gt;Before execution starts, JavaScript builds a blueprint of variable accessibility by analyzing the code structure.&lt;/p&gt;
&lt;p&gt;Think of it as answering this question:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;&quot;Which variables can each function access?&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That blueprint is called &lt;strong&gt;Lexical Scope&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;2-lexical-environment&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/@gauravsingh7x/javascript-lexical-scope-lexical-environment-scope-chain-closure-explained-like-the-js-engine-dc090baa273a&quot;&gt;2. Lexical Environment&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;strong&gt;Lexical Environment&lt;/strong&gt; is an internal object created whenever JavaScript starts executing a scope.&lt;/p&gt;
&lt;p&gt;It stores:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Local variables&lt;/li&gt;
&lt;li&gt;Function declarations&lt;/li&gt;
&lt;li&gt;A reference to its parent lexical environment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It consists of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Environment Record&lt;/strong&gt; → Stores variables and functions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Outer Reference&lt;/strong&gt; → Points to the parent lexical environment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Together, these make variable lookup possible.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;scope-chain&quot;&gt;Scope Chain&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;Scope Chain&lt;/strong&gt; is formed by connecting lexical environments through their &lt;strong&gt;Outer References&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When JavaScript can't find a variable in the current scope, it walks up this chain until it either finds the variable or reaches the global scope.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;easy-way-to-remember&quot;&gt;Easy Way to Remember&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Lexical Scope&lt;/strong&gt; is the rule that defines what a function can access.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Lexical Environment&lt;/strong&gt; is the place where those variables are actually stored.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;interview-definition&quot;&gt;Interview Definition&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Lexical Scope defines what a function can access, while the Lexical Environment stores those variables and maintains the relationship between parent and child scopes.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;example&quot;&gt;Example&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const globalVar = &quot;I am Global&quot;;

function outerFunction() {
  const outerVar = &quot;I am Outer&quot;;

  function innerFunction() {
    const innerVar = &quot;I am Local&quot;;

    console.log(innerVar);
    console.log(outerVar);
    console.log(globalVar);
  }

  innerFunction();
}

outerFunction();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;output-1&quot;&gt;Output&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;I am Local
I am Outer
I am Global
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id=&quot;what-happens-behind-the-scenes-&quot;&gt;What Happens Behind the Scenes?&lt;/h2&gt;
&lt;p&gt;When &lt;code&gt;innerFunction()&lt;/code&gt; starts executing:&lt;/p&gt;
&lt;p&gt;JavaScript creates a brand new &lt;strong&gt;Lexical Environment&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It contains:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Lexical Environment (innerFunction)

Environment Record
------------------
innerVar

Outer Reference
      ↓
Lexical Environment (outerFunction)

Environment Record
------------------
outerVar

Outer Reference
      ↓
Global Lexical Environment

Environment Record
------------------
globalVar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now suppose JavaScript needs &lt;code&gt;outerVar&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The lookup process becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Current Scope
      ↓
Parent Scope
      ↓
Global Scope
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This lookup path is called the &lt;strong&gt;Scope Chain&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;3-closure&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/@gauravsingh7x/javascript-lexical-scope-lexical-environment-scope-chain-closure-explained-like-the-js-engine-dc090baa273a&quot;&gt;3. Closure&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A &lt;strong&gt;Closure&lt;/strong&gt; is formed when a function &lt;strong&gt;remembers and retains access to its outer lexical environment even after the outer function has finished execution.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;in-my-style&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/gauravsingh7x/&quot;&gt;In My Style&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;When we return an inner function, pass it as a callback, or store it in a variable, and it carries its lexical environment along with it, that is called a Closure.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;example-1&quot;&gt;Example&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;function outerFunction() {
  let a = 10;

  function innerFunction() {
    a++;
    console.log(a);
  }

  return innerFunction;
}

const fn = outerFunction();

fn();
fn();
fn();
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;output-2&quot;&gt;Output&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;11
12
13
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id=&quot;why-doesn-t-a-disappear-&quot;&gt;Why Doesn't &lt;code&gt;a&lt;/code&gt; Disappear?&lt;/h2&gt;
&lt;p&gt;Normally, when &lt;code&gt;outerFunction()&lt;/code&gt; finishes execution, its execution context is removed from the call stack.&lt;/p&gt;
&lt;p&gt;But JavaScript notices that &lt;strong&gt;&lt;code&gt;innerFunction&lt;/code&gt; still needs &lt;code&gt;a&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Instead of destroying that memory, JavaScript keeps the lexical environment alive.&lt;/p&gt;
&lt;p&gt;The returned function holds a hidden reference to it.&lt;/p&gt;
&lt;p&gt;This preserved relationship is called a &lt;strong&gt;Closure&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;one-snap-gt-100-closure-definitions&quot;&gt;One Snap &amp;gt; 100 Closure Definitions&lt;/h2&gt;
&lt;p&gt;Someone asks:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;&quot;Where is the closure?&quot;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Open Chrome DevTools:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.dir(fn)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Expand:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;[[Scopes]]

Closure (outerFunction)
{
    a: 13
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There it is.&lt;/p&gt;
&lt;p&gt;That hidden &lt;strong&gt;Closure&lt;/strong&gt; object is the preserved lexical environment that keeps your variables alive even after the outer function has returned.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/@gauravsingh7x/javascript-lexical-scope-lexical-environment-scope-chain-closure-explained-like-the-js-engine-dc090baa273a&quot;&gt;Final One-Line Difference&lt;/a&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Concept                 &lt;/th&gt;&lt;th&gt;Meaning&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Lexical Scope&lt;/strong&gt;       &lt;/td&gt;&lt;td&gt;Defines what a function can access.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Lexical Environment&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Stores variables and references to parent scopes.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Scope Chain&lt;/strong&gt;         &lt;/td&gt;&lt;td&gt;The path JavaScript follows to find variables.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Closure&lt;/strong&gt;             &lt;/td&gt;&lt;td&gt;A function together with the preserved lexical environment it remembers after the outer function has finished execution.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;key-takeaways&quot;&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/@gauravsingh7x/javascript-lexical-scope-lexical-environment-scope-chain-closure-explained-like-the-js-engine-dc090baa273a&quot;&gt;Key Takeaways&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;⟶ Lexical means &lt;strong&gt;where code is written&lt;/strong&gt;.&lt;br&gt;
⟶ Scope is determined during parsing, not during function calls.&lt;br&gt;
⟶ Every executing scope gets its own Lexical Environment.&lt;br&gt;
⟶ Lexical Environments are connected through Outer References.&lt;br&gt;
⟶ Those references create the Scope Chain.&lt;br&gt;
⟶ A Closure keeps a lexical environment alive as long as a function still references it.&lt;/p&gt;
&lt;p&gt;If this article helped you understand what's happening &lt;strong&gt;inside the JavaScript engine&lt;/strong&gt;, consider leaving a ❤️ and sharing it with fellow developers.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/@gauravsingh7x/javascript-lexical-scope-lexical-environment-scope-chain-closure-explained-like-the-js-engine-dc090baa273a&quot;&gt;Happy Coding!&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/22067/javascript-lexical-scope-lexical-environment-scope-chain-closure-explained-like-engine</guid>
<pubDate>Tue, 07 Jul 2026 17:33:44 +0000</pubDate>
</item>
</channel>
</rss>