How JavaScript Works Behind the Scenes

November 19, 2024 (2mo ago)

JavaScript Behind the Scenes

JavaScript is a single-threaded, non-blocking, asynchronous programming language. Let's explore how it works under the hood.

Execution Context

When JavaScript code runs, it creates an execution context which has two phases:

// Creation Phase Example
console.log(name); // undefined (hoisting)
var name = "JavaScript";
 
// Execution Phase Example
function greet() {
  console.log("Hello " + name);
}
greet(); // "Hello JavaScript"

Creation Phase

Execution Phase

Call Stack

function first() {
  console.log("First");
  second();
}
 
function second() {
  console.log("Second");
  third();
}
 
function third() {
  console.log("Third");
}
 
first();
 
// Call Stack:
// 1. first()
// 2. second()
// 3. third()

Event loop

JavaScript uses an event loop to handle asynchronous operations:

console.log("Start");
 
setTimeout(() => {
  console.log("Timeout");
}, 0);
 
Promise.resolve().then(() => {
  console.log("Promise");
});
 
console.log("End");
 
// Output:
// Start
// End
// Promise
// Timeout

The event loop follows this order:

  1. Synchronous code first
  2. Microtasks (Promises) next
  3. Macrotasks (setTimeout, setInterval) last

Memory Management

JavaScript automatically manages memory through garbage collection:

let user = {
  name: "John",
};
 
user = null; // Object becomes eligible for garbage collection

Key concepts:

Scope and Closures

JavaScript uses lexical scoping and closures:

function outer() {
  let count = 0;
 
  return function inner() {
    return count++;
  };
}
 
const counter = outer();
console.log(counter()); // 0
console.log(counter()); // 1

Prototypes and Inheritance

JavaScript uses prototypal inheritance:

function Animal(name) {
  this.name = name;
}
 
Animal.prototype.speak = function () {
  return `${this.name} makes a sound`;
};
 
const dog = new Animal("Rex");
console.log(dog.speak()); // "Rex makes a sound"

Key Takeaways

  1. JavaScript is single-threaded but handles async operations via the event loop
  2. Every piece of code runs in an execution context
  3. Memory is managed automatically through garbage collection
  4. Scope determines variable accessibility
  5. Prototypes enable inheritance

Understanding these concepts helps write more efficient and maintainable JavaScript code.