5. Variables and Scope

Variable Declaration

ECMAScript provides three ways to declare variables:

var (Legacy)

var x = 10;
var y;        // undefined
y = 20;

Problems with var:

let (ES6+)

let x = 10;
let y;        // undefined
y = 20;

// Cannot redeclare in same scope
// let x = 5; // Error!

const (ES6+)

const PI = 3.14159;
const CONFIG = { debug: true };

// Must be initialized
// const x; // Error!

// Cannot reassign
// PI = 3.14; // Error!

// But can modify object properties
CONFIG.debug = false; // OK

Scope

Global Scope

Variables declared outside any function:

let globalVar = "I'm global";

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

Function Scope

Variables declared with var are function-scoped:

function example() {
    var functionScoped = "inside function";
    console.log(functionScoped); // OK
}
// console.log(functionScoped); // Error: not defined

Block Scope

Variables declared with let and const are block-scoped:

if (true) {
    let blockScoped = "inside block";
    console.log(blockScoped); // OK
}
// console.log(blockScoped); // Error: not defined

Hoisting

var Hoisting

console.log(hoisted); // undefined (not error!)
var hoisted = "I'm hoisted";

Equivalent to:

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

let/const Hoisting

// console.log(notHoisted); // Error: Cannot access before initialization
let notHoisted = "I'm not hoisted";

Temporal Dead Zone (TDZ)

The period between entering scope and variable declaration:

{
    // TDZ starts here
    console.log(x); // Error: x is in TDZ
    let x = 5;      // TDZ ends here
}

Best Practices

  1. Use const by default: Prevents accidental reassignment
  2. Use let when you need to reassign: For counters, loops, etc.
  3. Avoid var: Use let/const instead
  4. Declare variables at the top of scope: Improves readability
  5. Use meaningful names: userName instead of u

Examples

Counter with let

function countToTen() {
    for (let i = 1; i <= 10; i++) {
        console.log(i);
    }
    // i is not accessible here
}

Configuration with const

const APP_CONFIG = {
    apiUrl: 'https://api.example.com',
    timeout: 5000,
    retries: 3
};

// APP_CONFIG = {}; // Error: cannot reassign
APP_CONFIG.timeout = 10000; // OK: can modify properties

Block scoping in loops

for (let i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 100); // Prints 0, 1, 2
}

for (var j = 0; j < 3; j++) {
    setTimeout(() => console.log(j), 100); // Prints 3, 3, 3 (closure issue)
}

Next Steps

Understanding variables and scope is crucial. Next, let's explore data types in ECMAScript.