Skip to main content

Variable Declarations

Understanding how JavaScript handles variables is the foundation of mastering the language. It’s not just about syntax; it’s about how the JS Engine prepares your code before a single line is executed.

1. The Legacy: var

Before ES6, var was the only way to declare variables. It behaves differently than modern keywords because it ignores block scope (like if statements or for loops).

Scope: Global vs. Function

  • Global Scope: When declared outside a function, it attaches to the window object (in browsers).
  • Function Scope: When declared inside a function, it is trapped there and cannot be accessed from outside.
Visualizing Function Scope
JavaScript Runtime
Console Output

Re-declaration & Updates

One of the "quirks" of var is that it allows you to re-declare the same variable name without an error. In large codebases, this often leads to accidental bugs.

The 'Silent' Re-declaration
JavaScript Runtime
Console Output
Technical Insight

A repeated var declaration in the same scope is effectively a do-nothing operation. The JS engine sees the first one and ignores subsequent declarations of the same name.

2. Hoisting: The "Pre-Process" Phase

Hoisting is a mental metaphor for how the JS Engine sets up the program. Think of it as a two-pass system:

  1. Pass 1 (Compile/Setup): Find all declarations and "hoist" them to the top.
  2. Pass 2 (Execution): Run the code line-by-line.

How var Hoists

When var is hoisted, it is automatically initialized with undefined.

The Hoisting Transformation
// What you write:
console.log(age); // undefined
var age = 25;

// How JS interprets it:
var age; // 1. Declaration hoisted & initialized to undefined
console.log(age); // 2. Logs undefined
age = 25; // 3. Assignment happens here

Function Hoisting Priority

Functions are the "VIPs" of hoisting. They are moved to the top before variable declarations.

Challenge: Function vs. Var Hoisting
JavaScript Runtime
Console Output

3. The Modern Way: let & const

While var is function-scoped, let and const are block-scoped { }. They also exist in a "Temporal Dead Zone" (TDZ) which prevents them from being used before they are declared—making your code much safer.

Featurevarletconst
ScopeFunctionBlockBlock
HoistingYes (undefined)Yes (TDZ)Yes (TDZ)
Re-declareYesNoNo
Re-assignYesYesNo

Interactive Challenges

Test your understanding of the execution context with these common interview scenarios.

Puzzle: The Hoisting Order
JavaScript Runtime
Console Output
Deep Dive

For a deeper understanding of these mechanics, I highly recommend checking out: