Scope and Hoisting in JavaScript
In JavaScript, scope and hoisting are two fundamental concepts that determine how and where variables and functions are accessed in your code.
Understanding these helps prevent bugs, avoid unexpected results, and write more predictable, efficient programs.
Function Scope (var, let, const)
What is Scope?
Scope defines the visibility and lifetime of variables — in other words, where in your program you can access a variable.
In JavaScript, there are three main types of scope:
- Global Scope
- Function Scope
- Block Scope
Function Scope Explained
When you declare a variable inside a function, it is only accessible within that function — not outside it.
Each function creates its own scope.
Example:
function greet() {
let message = "Hello, world!";
console.log(message); // Accessible here
}
greet();
console.log(message); // Error: message is not defined
How var, let, and const behave in Function Scope
var
var
has function scope.- It means that if declared anywhere inside a function, it’s visible throughout that function (even before its declaration, due to hoisting).
function example() {
console.log(x); // undefined (due to hoisting)
var x = 10;
console.log(x); // 10
}
example();
let and const
- Both
let
andconst
have block scope (not function scope). - This means they are only available inside the block
{}
where they are declared. - They are not initialized until the execution reaches their declaration line (known as the Temporal Dead Zone).
function demo() {
if (true) {
let a = 5;
const b = 10;
console.log(a, b); // 5 10
}
console.log(a); // Error: a is not defined
}
demo();
Function Scope Summary Table
Keyword | Scope Type | Hoisted | Reassignment | Best Use |
---|---|---|---|---|
var | Function Scope | Yes (initialized as undefined ) | Yes | Legacy code, avoid if possible |
let | Block Scope | Yes (but not initialized) | Yes | Reassignable variables |
const | Block Scope | Yes (but not initialized) | No | Constants and fixed references |
Hoisting of Function Declarations
What is Hoisting?
Hoisting is JavaScript’s default behavior of moving declarations to the top of their scope (before the code executes).
This applies to:
- Variables (declared with
var
) - Function Declarations
It means you can call a function before it’s defined in your code.
Example: Function Hoisting
sayHello(); // Works! Output: Hello there!
function sayHello() {
console.log("Hello there!");
}
Function Declarations vs Function Expressions in Hoisting
Type | Example | Hoisted? | Usable Before Definition? |
---|---|---|---|
Function Declaration | function greet() {} | Yes | Yes |
Function Expression | const greet = function() {} | Partially (variable hoisted, not function) | No |
Arrow Function | const greet = () => {} | Partially (variable hoisted, not function) | No |
Example:
- Function expressions and arrow functions are not hoisted with their body.
- Only their variable name is hoisted — not the assignment.
greet(); // Error: Cannot access 'greet' before initialization
const greet = function() {
console.log("Hi!");
};
Hoisting Example (Variable + Function)
console.log(num); // undefined
sayHi(); // Hello!
var num = 10;
function sayHi() {
console.log("Hello!");
}