Variable Scope in JavaScript

Variable scope determines where a variable is accessible within a program. JavaScript supports two primary types of scope: global and local.

Global Scope

Variables declared outside of any function or block are in the global scope. They are accessible from anywhere in the code.

let globalVar = "I'm global";

function checkScope() {
  console.log(globalVar); // Accessible
}

checkScope();

Function Scope (var)

Variables declared with var are function-scoped, meaning they are accessible within the entire function, regardless of block structure.

function example() {
  var functionVar = "I'm function-scoped";
  if (true) {
    var functionVar = "Reassigned inside block";
    console.log(functionVar); // "Reassigned inside block"
  }
  console.log(functionVar); // "Reassigned inside block"
}

Block Scope (let and const)

Variables declared with let and const are block-scoped, meaning they are only accessible within the block they are declared in.

function example() {
  let blockVar = "I'm block-scoped";
  if (true) {
    let blockVar = "Reassigned inside block";
    console.log(blockVar); // "Reassigned inside block"
  }
  console.log(blockVar); // "I'm block-scoped"
}
DeclarationScopeReassignmentRedeclaration
varFunctionYesYes
letBlockYesNo
constBlockNoNo

Hoisting in JavaScript

Hoisting is the default behavior of JavaScript where variable and function declarations are moved to the top of their scope during the compilation phase. However, only the declarations are hoisted, not the assignments.

Hoisting with var

console.log(hoistedVar); // undefined
var hoistedVar = "I'm hoisted";

Hoisting with let and const

console.log(hoistedLet); // ReferenceError: hoistedLet is not defined
let hoistedLet = "I'm hoisted";

The let and const declarations are hoisted but not initialized, leading to a "temporal dead zone" where accessing them before declaration results in a ReferenceError.

Best Practices

  1. Prefer let and const over var to avoid unexpected behavior from function scope and hoisting.
  2. Use const for values that should not change to enforce immutability.
  3. Avoid global variables to prevent naming conflicts and improve maintainability.
  4. Understand the temporal dead zone when using let and const to avoid runtime errors.

Learn more with useful resources