Skip to main content

Variables, Declarations, and Scope Mechanics

In JavaScript, variables store data values, but how and where you declare them dictates their lifecycle, accessibility, and mutability. Understanding variable declarations and scoping mechanics is essential to writing clean, bug-free code.

Declaration Types: var vs let vs const

JavaScript offers three keywords for variable declaration: var (ES5), let (ES6), and const (ES6).

Featurevarletconst
Scope LevelFunction / GlobalBlock Scope {}Block Scope {}
Re-declarationAllowedSyntax ErrorSyntax Error
Re-assignmentAllowedAllowedTypeError
Hoisting BehaviorInitialized as undefinedUninitialized (Temporal Dead Zone)Uninitialized (Temporal Dead Zone)
Global Object PropertyYes (window.x)NoNo

Scope Types Explained

Scope determines the visibility and accessibility of variables in different parts of your code.

Scope Hierarchy
├── Global Scope -> Accessible anywhere in the execution context
├── Function Scope -> Bound inside function boundary (var, let, const)
└── Block Scope -> Bound inside block curly braces {} (let, const only)

1. Global Scope

Variables declared outside any function or block belong to the global scope.

Global Scope Example
JavaScript Runtime
Console Output
note

When you run the above code, the output is undefined because the variable globalAppTitle is declared in the global scope and is accessible inside the function printTitle().

So, when we call printTitle(), it logs the value of globalAppTitle to the console.

For example:

const globalAppTitle = "JavaScript Mastery";

function printTitle() {
console.log(globalAppTitle); // Accessible here
}
printTitle(); // Logs: "JavaScript Mastery"

2. Block Scope (let / const)

Variables declared with let and const inside {} cannot be accessed outside that block.

Block Scope Example
JavaScript Runtime
Console Output

Hoisting & The Temporal Dead Zone (TDZ)

Hoisting is JavaScript's default behavior of moving declarations to the top of their containing scope during the compilation phase prior to code execution.

var Hoisting

Declarations are hoisted and initialized with undefined.

var Hoisting Example
JavaScript Runtime
Console Output

let and const Hoisting (The TDZ)

let and const variables are hoisted, but remain uninitialized. The time between entering scope and variable declaration is called the Temporal Dead Zone (TDZ).

Temporal Dead Zone Example
JavaScript Runtime
Console Output

Interactive Playground: Scope Exploration

Try editing the script below to observe how block scope and variable re-assignments behave live:

Scope Playground
JavaScript Runtime
Console Output

Best Practices

  1. **Default to const**: Protect variables from unintended re-assignments.
  2. Use let for reassignment: Use only when values must mutate (e.g., loop counters, accumulators).
  3. **Avoid var**: Prevent scope-leakage issues and silent hoisting bugs in modern applications.

Knowledge Check

Exercise Requirements:

  1. Fix the variable declarations below so no variables leak outside the if block.
  2. Ensure API_KEY cannot be accidentally reassigned later in execution.
Solution
JavaScript Runtime
Console Output
Next Up

Now that you understand variable lifetimes and scoping, proceed to Data Types and Type Coercion!