HomeBytesheetsRoadmapsUI TemplatesUI ToolsStack Discussion
4 Topics
Chapter•60 Minutes

Variables, Scope, Hoisting, and Temporal Dead Zones

Build a precise understanding of var, let, const, lexical environments, scope chains, hoisting, and why declarations behave differently.

var, let, and const

var is function-scoped, while let and const are block-scoped. const prevents reassignment of the binding, but it does not make referenced objects immutable. This distinction between binding immutability and object immutability is essential.

Modern JavaScript generally favors const by default and let when reassignment is actually required.

Binding vs Object Mutation
const user = { name: 'Suriya' };

user.name = 'Alex';
console.log(user.name);

// user = {}; // TypeError
💡 The const binding cannot point to another object, but the object itself remains mutable unless you explicitly enforce immutability.
Key Takeaways
  • var is function-scoped.
  • let and const are block-scoped.
  • const protects a binding, not the contents of an object.
Knowledge Check

What does `const` guarantee?

Lexical Scope and the Scope Chain

JavaScript uses lexical scoping: where a function is written determines which outer variables it can access. When an identifier is referenced, JavaScript searches the current lexical environment and then walks outward through enclosing environments until it finds the binding or reaches the global environment.

This lexical relationship is the foundation for closures.

Scope Lookup
Key Takeaways
  • Scope is determined by lexical structure.
  • Identifier lookup proceeds through enclosing environments.
  • Closures depend on lexical environments remaining accessible.
Knowledge Check

What primarily determines which outer variables a function can access?

Hoisting Is Not Moving Code

Hoisting is a useful informal term for the fact that declarations are processed before execution of their surrounding code. It does not mean JavaScript literally moves source lines to the top.

Function declarations can generally be called before their declaration. var declarations are initialized with undefined, while let and const bindings exist but cannot be accessed before initialization because of the Temporal Dead Zone.

Different Declaration Behavior
sayHello();

function sayHello() {
  console.log('Hello');
}

console.log(value);
var value = 10;

// console.log(count); // ReferenceError
let count = 10;
💡 The function declaration is available during execution. The var binding exists with undefined before its assignment. The let binding exists but cannot be accessed before initialization.
Key Takeaways
  • Hoisting is about declaration instantiation, not textual movement.
  • var can be observed as undefined before assignment.
  • let and const have a Temporal Dead Zone before initialization.
Knowledge Check

What happens when code accesses a `let` variable before its declaration is initialized?

Temporal Dead Zone

The Temporal Dead Zone (TDZ) is the period between entering a scope where a lexical binding exists and reaching the declaration's initialization. During that period, reading or accessing the binding results in a ReferenceError.

The TDZ is a runtime concept, not merely a parser restriction. This explains why typeof someLetVariable can throw when the variable is in the TDZ.

TDZ in Action
{
  // console.log(typeof name); // ReferenceError
  let name = 'Suriya';
  console.log(typeof name);
}
💡 The lexical binding exists when the block begins, but it is uninitialized until the let declaration executes.
Key Takeaways
  • TDZ applies to let, const, and class declarations.
  • A lexical binding can exist without being initialized.
  • TDZ helps prevent accidental use of variables before initialization.
Knowledge Check

Which declaration is subject to the Temporal Dead Zone?