JavaScript Scope

📚 Lesson 8 of 22  •  ⏱ 12 min read  •  Intermediate

Global vs Local Scope

JavaScript
const siteName = "AnnauniversityPlus";  // global — accessible everywhere

function greet() {
  const message = "Hello";  // local — only inside greet()
  console.log(siteName);    // works — can access global
  console.log(message);    // works
}

greet();
console.log(message);  // ReferenceError: message is not defined

Block Scope — let & const

JavaScript
// let and const are block-scoped (inside {} )
if (true) {
  let x = 10;
  const y = 20;
}
console.log(x);  // ReferenceError
console.log(y);  // ReferenceError

// var is function-scoped — leaks out of blocks
if (true) {
  var z = 30;
}
console.log(z);  // 30 — var leaks out! (use let/const instead)

Hoisting

JavaScript
// var declarations are hoisted (moved to top of function)
console.log(a);  // undefined (not an error — var is hoisted)
var a = 5;

// let/const are hoisted but NOT initialized (temporal dead zone)
console.log(b);  // ReferenceError: Cannot access 'b' before initialization
let b = 10;

// Function declarations are fully hoisted
greet();  // Works! Function is hoisted with its body
function greet() { console.log("hi"); }

// Function expressions are NOT hoisted
sayHi();  // TypeError: sayHi is not a function
const sayHi = () => {};

Closures

JavaScript
// A closure remembers variables from its outer scope
function makeCounter() {
  let count = 0;  // private to makeCounter

  return {
    increment: () => ++count,
    decrement: () => --count,
    value:     () => count
  };
}

const counter = makeCounter();
counter.increment();  // 1
counter.increment();  // 2
counter.decrement();  // 1
counter.value();      // 1
// count is not directly accessible outside — it's encapsulated

Practical Closure — Memoization

JavaScript
function memoize(fn) {
  const cache = {};
  return function(n) {
    if (cache[n] !== undefined) return cache[n];
    cache[n] = fn(n);
    return cache[n];
  };
}

const factorial = memoize(function fact(n) {
  return n <= 1 ? 1 : n * fact(n - 1);
});

factorial(5);  // computed: 120
factorial(5);  // from cache: 120 (fast!)