Lesson 38-In-Depth Analysis of Advanced JavaScript Syntax

Execution Environment and Runtime Mechanisms

Execution Context Stack and Call Stack

JavaScript’s Execution Context Stack (also known as the call stack) is the core mechanism for managing code execution order. Each time a function is called, a new execution context is created and pushed onto the stack. When the function completes, its context is popped off the stack.

function first() {
  console.log('First function');
  second();
}

function second() {
  console.log('Second function');
  third();
}

function third() {
  console.log('Third function');
}

first();

Call stack changes during execution:

  1. Global execution context is pushed onto the stack.
  2. first function execution context is pushed.
  3. second function execution context is pushed.
  4. third function execution context is pushed.
  5. third completes, its context is popped.
  6. second completes, its context is popped.
  7. first completes, its context is popped.
  8. Global execution context is popped.

Variable Environment and Lexical Environment

An execution context consists of a Variable Environment and a Lexical Environment:

  • Variable Environment: Stores var-declared variables and function declarations.
  • Lexical Environment: Stores let/const-declared variables, enabling block-level scoping.
function example() {
  var a = 1; // Stored in variable environment
  let b = 2; // Stored in lexical environment
  const c = 3; // Stored in lexical environment

  if (true) {
    var d = 4; // Still in variable environment
    let e = 5; // New lexical environment
    const f = 6; // New lexical environment
  }

  console.log(d); // 4, var ignores block scope
  // console.log(e); // ReferenceError, e is not visible outside
}

Scope Chain and Identifier Resolution

Identifier resolution follows the scope chain, searching upward:

  1. Check the current lexical environment.
  2. If not found, check the parent lexical environment.
  3. Continue up to the global environment.
  4. If not found in the global environment, throw a ReferenceError.
let globalVar = 'global';

function outer() {
  let outerVar = 'outer';

  function inner() {
    let innerVar = 'inner';
    console.log(innerVar); // Current lexical environment
    console.log(outerVar); // Parent lexical environment
    console.log(globalVar); // Global environment
  }

  inner();
}

outer();

Garbage Collection Mechanism

Mark-and-Sweep Algorithm

The V8 engine primarily uses the mark-and-sweep algorithm for garbage collection:

  1. Mark Phase: Starting from root objects (global variables, variables in the current execution context, etc.), mark all reachable objects.
  2. Sweep Phase: Traverse heap memory, reclaim unmarked objects.
// Example: Object reference relationships
let obj1 = { name: 'Object 1' }; // Root-reachable
let obj2 = { name: 'Object 2' }; // Root-reachable
obj1.ref = obj2; // obj1 references obj2
obj2.ref = obj1; // obj2 references obj1, forming a circular reference

// Even if obj1 and obj2 become unreachable from the root, traditional reference counting cannot reclaim them
obj1 = null;
obj2 = null;

// Mark-and-sweep can reclaim them, as they are no longer reachable from the root

Generational Garbage Collection

V8 divides heap memory into new space and old space:

  • New Space: Stores short-lived objects, using the Scavenge algorithm.
  • Old Space: Stores long-lived objects, using mark-and-sweep and mark-and-compact algorithms.
// New space object example
function createShortLivedObjects() {
  for (let i = 0; i < 10000; i++) {
    let temp = { data: i }; // New space object
    // Becomes unreferenced soon after use
  }
}

// Old space object example
let longLivedObject = { data: 'persistent' };
function updateLongLivedObject() {
  longLivedObject.data = 'updated'; // Persists long-term
}

Common Memory Leak Patterns

  1. Accidental Global Variables:
function leak() {
  leakedVar = 'This is a global variable'; // Accidentally creates a global variable
}
  1. Forgotten Timers or Callbacks:
let someResource = getData();
setInterval(() => {
  const node = document.getElementById('node');
  if (node) {
    node.innerHTML = JSON.stringify(someResource);
  }
}, 1000);
// someResource remains referenced even if no longer needed
  1. Closures Retaining Large Objects:
function outer() {
  const bigData = new Array(1000000).fill('data');
  return function inner() {
    console.log('This closure keeps bigData in memory');
  };
}
const closure = outer(); // bigData cannot be reclaimed

V8 Engine’s Just-In-Time (JIT) Compilation

V8 Compilation Pipeline

V8 uses a multi-tier compilation strategy:

  1. Ignition Interpreter: Quickly generates bytecode.
  2. TurboFan Compiler: Compiles hot code into optimized machine code.
  3. Deoptimization: Reverts to the interpreter when assumptions fail.
function add(a, b) {
  return a + b;
}

// Initial execution: Ignition interpreter generates bytecode
add(1, 2);

// After repeated calls: TurboFan compiles to optimized machine code
for (let i = 0; i < 100000; i++) {
  add(i, i + 1);
}

// If non-numeric arguments are passed:
add('1', '2'); // May trigger deoptimization

Hidden Classes and Inline Caching

V8 uses hidden classes to optimize object property access:

function Point(x, y) {
  this.x = x;
  this.y = y;
}

const p1 = new Point(1, 2); // Creates a hidden class
const p2 = new Point(3, 4); // Reuses the same hidden class

// Adding a new property creates a new hidden class
p1.z = 3; // p1 now has a new hidden class

Inline caching optimizes property access:

function getProp(obj) {
  return obj.x; // First call records the hidden class
}

const obj1 = { x: 1 };
getProp(obj1); // Records obj1’s hidden class

const obj2 = { x: 2 }; // Same hidden class
getProp(obj2); // Directly uses cached access path

Inlining Optimization

TurboFan inlines hot functions to reduce call overhead:

function square(x) {
  return x * x;
}

function calculate() {
  let sum = 0;
  for (let i = 0; i < 1000; i++) {
    sum += square(i); // May be inlined as sum += i * i
  }
  return sum;
}

Membership Required

You must be a member to access this content.

View Membership Levels

Already a member? Log in here
Share your love