JavaScript Scope
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!)