Scope and Hoisting
9 min read
Scope
Scope determines where in your code a variable is accessible. JavaScript has three levels: global scope, function scope, and block scope (let/const only).
javascript
const global = "I am global";
function outer() {
const outerVar = "outer";
function inner() {
const innerVar = "inner";
console.log(global); // OK — outer scope
console.log(outerVar); // OK — lexical scope
console.log(innerVar); // OK
}
inner();
// console.log(innerVar); // ReferenceError
}
// Block scope
{
let blockScoped = "only here";
var notBlockScoped = "leaks out!";
}
// console.log(blockScoped); // ReferenceError
console.log(notBlockScoped); // "leaks out!"Hoisting
Hoisting is JavaScript's behaviour of moving declarations to the top of their scope before code runs. Function declarations are hoisted fully (you can call them before their definition). var declarations are hoisted but not their values. let and const are hoisted but sit in the Temporal Dead Zone until their line.
javascript
sayHello(); // works! function declarations are fully hoisted
function sayHello() {
console.log("Hello");
}
console.log(x); // undefined (var hoisted, value not)
var x = 5;
// console.log(y); // ReferenceError (TDZ)
let y = 10;Relying on hoisting is a code smell. Declare variables before using them and prefer const/let to make intent clear.
Ready to test yourself?
Practice JavaScript— quiz & coding exercises