In JavaScript, scope and hoisting determine how variables and functions are accessed and initialized. Understanding them is crucial to avoid bugs and write clean code.
1. JavaScript Scope
Scope defines the visibility and lifetime of variables. There are three main types:
a) Global Scope
Variables declared outside any function are global and accessible anywhere:
let globalVar = "I am global";
function showGlobal() {
console.log(globalVar);
}
showGlobal(); // Output: I am global
console.log(globalVar); // Output: I am global
b) Function (Local) Scope
Variables declared inside a function are local to that function:
function greet() {
let message = "Hello!";
console.log(message);
}
greet(); // Output: Hello!
console.log(message); // Error: message is not defined
c) Block Scope
Variables declared with let or const inside {} are block-scoped:
if (true) {
let blockVar = "Inside block";
const constVar = "Also inside block";
console.log(blockVar); // Inside block
}
console.log(blockVar); // Error: blockVar is not defined
Tip:
varis not block-scoped, it is function-scoped.
2. Hoisting
Hoisting is JavaScript’s default behavior of moving declarations to the top of their scope before code execution.
console.log(hoistedVar); // undefined
var hoistedVar = 10;
- Variables declared with
varare hoisted and initialized asundefined. - Variables declared with
letandconstare hoisted but not initialized (accessing them before declaration gives a ReferenceError).
console.log(name); // ReferenceError
let name = "Alice";
- Functions declared using
functionkeyword are fully hoisted:
greet(); // Output: Hello!
function greet() {
console.log("Hello!");
}
- Function expressions and arrow functions are not hoisted in the same way:
sayHi(); // Error
const sayHi = () => console.log("Hi!");
3. Practical Tips
- Always declare variables at the top of their scope to avoid confusion.
- Use
letandconstinstead ofvarto prevent unexpected behaviors. - Understanding hoisting helps debug errors like
undefinedandReferenceError.
Mastering scope and hoisting is essential to write predictable, maintainable, and bug-free JavaScript code.
Citations: