HomeJAVASCRIPTHow Javascript Works And Code is executed

How Javascript Works And Code is executed

1. JavaScript Execution Overview

JavaScript runs in two main phases for any given code:

  1. Creation Phase (a.k.a. “Memory Allocation Phase”)
    • Variables and functions are set up in memory before any code actually runs.
    • Functions are fully stored in memory.
    • Variables are assigned undefined (for var) or left in TDZ (Temporal Dead Zone) for let/const until initialized.

    Happens before any code is executed.

    • Variables declared with var get undefined.
    • Functions are hoisted fully (function declarations, not expressions).
    • let and const are placed in Temporal Dead Zone (TDZ) — you can’t access them before their line of code executes.
    • this is set (depends on how the code runs).
    • Outer scope reference (Lexical Environment link) is set.

    2. Execution Phase

    • Code is executed line-by-line.
    • Variables get actual values.
    • Functions get called and create new execution contexts.

    Lexical Environment & Scope Chain

    Lexical Environment =
    Current EC’s Variable Environment + Reference to Outer Environment.

    • When a variable is not found in the current EC, JavaScript follows the scope chain outward.
    • This is based on where functions are physically written in the code (lexical scope), not where they’re called from.

    Example:

    let x = 10;
    
    function outer() {
        let y = 20;
    
        function inner() {
            console.log(x, y); // looks in inner → outer → global
        }
        inner();
    }
    
    outer(); // prints 10 20
    

    📌 Even though inner() is executed inside outer(), it remembers where it was written, so it can access x and y.

    2. Execution Context

    An Execution Context (EC) is an environment where JavaScript code is evaluated and executed.

    There are three types:

    1. Global Execution Context (GEC) – Created first, runs your whole file.
      • this refers to the global object (window in browsers, global in Node.js).
    2. Function Execution Context (FEC) – Created when a function is invoked.
    3. Eval Execution Context – Rare, for eval() calls.

    Every EC has three main parts:

    • Variable Environment – Stores variables and function declarations.
    • Lexical Environment – Keeps track of variable scope and outer scope reference.
    • this Binding – Sets the value of this depending on how the function is called.

    3. Call Stack

    The Call Stack is where JavaScript keeps track of which execution context is currently running.

    • It’s LIFO (Last In, First Out).
    • When a function is called, a new EC is pushed onto the stack.
    • When a function finishes, its EC is popped from the stack.

    JavaScript runs synchronously in the call stack, but asynchronous tasks (timers, API calls, promises) use:

    • Web APIs → handle async work in browser/Node.
    • Callback Queue / Task Queue → stores callbacks ready to run.
    • Event Loop → moves tasks from the queue into the call stack when it’s empty.

    Example:

    console.log("1");
    
    setTimeout(() => {
        console.log("2");
    }, 0);
    
    console.log("3");
    
    // Output: 132
    

    Here:

    1. "1" goes straight to stack → printed.
    2. setTimeout sends the callback to Web API, waits for timer → then moves it to queue.
    3. "3" is printed.
    4. Event loop sees stack empty → pushes "2" callback to stack.

    4. Step-by-Step Example

    var a = 10;
    
    function foo() {
        var b = 20;
        console.log('Inside foo');
        bar();
    }
    
    function bar() {
        console.log('Inside bar');
    }
    
    foo();
    console.log('Done');
    

    Step 1: Creation Phase (Global Execution Context)

    • Memory is set up: a: undefined foo: function bar: function
    • this points to window (browser).
    • Outer environment is null (no parent above global).

    Step 2: Execution Phase (Global EC)

    1. a = 10
    2. foo() is called → new Function Execution Context for foo is created and pushed onto Call Stack.

    Step 3: Function foo Execution

    • Creation phase for foo: b: undefined
    • Execution phase:
      • b = 20
      • console.log('Inside foo') → prints "Inside foo"
      • bar() is called → new Function Execution Context for bar is created and pushed.

    Step 4: Function bar Execution

    • Creation phase for bar: (no vars except default arguments)
    • Execution phase:
      • console.log('Inside bar') → prints "Inside bar"
    • bar finishes → popped from stack.

    Step 5: Back to foo

    • foo finishes → popped from stack.

    Step 6: Back to Global

    • Executes console.log('Done') → prints "Done".
    • Global EC stays until program ends.

    5. Call Stack Flow (Visual)

    Initially:
    [ Global EC ]
    
    After foo() call:
    [ foo EC ]
    [ Global EC ]
    
    Inside foo, after bar() call:
    [ bar EC ]
    [ foo EC ]
    [ Global EC ]
    
    After bar returns:
    [ foo EC ]
    [ Global EC ]
    
    After foo returns:
    [ Global EC ]
    

    6. Key Notes

    • JavaScript is single-threaded → only one thing happens at a time in the call stack.
    • If a function takes too long, it blocks the call stack.
    • Async operations (setTimeout, Promises, fetch) work with Web APIs + Callback Queue + Event Loop, not directly in the stack.

    Share: 

    No comments yet! You be the first to comment.

    Leave a Reply

    Your email address will not be published. Required fields are marked *