Hoisting is a behavior in JavaScript where variables and function declarations are moved to the top of their containing scope during the compile phase, before the code is executed.
This means that you can use variables and functions before they are declared in the code.
How Hoisting Works:
- Variable Declarations (
var
,let
,const
):var
is hoisted with an initial value ofundefined
.let
andconst
are hoisted but not initialized. Accessing them before declaration results in a ReferenceError due to the temporal dead zone.
- Function Declarations:
- Function declarations are hoisted with their entire function definition.
- Function expressions and arrow functions are not hoisted like function declarations.
Examples:
1. Hoisting with var
:
console.log(a); // undefined
var a = 5;
console.log(a); // 5
Explanation:
The declaration var a
is hoisted to the top, but its assignment (a = 5
) is not. So a
is undefined
when accessed before assignment.
Behind the scenes (How JavaScript sees it):
var a;
console.log(a); // undefined
a = 5;
console.log(a); // 5
2. Hoisting with let
and const
:
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 15;
Explanation:
The declarations are hoisted, but they remain in the temporal dead zone (TDZ) until they are initialized.
3. Hoisting with Functions:
Function Declaration:
greet(); // Hello!
function greet() {
console.log('Hello!');
}
Explanation:
The entire function declaration is hoisted, so calling greet()
before its definition works.
Function Expression:
sayHello(); // TypeError: sayHello is not a function
var sayHello = function() {
console.log('Hello!');
}
Explanation:
Only the variable sayHello
is hoisted (with undefined
), not the function assignment.
Key Takeaways:
Declaration Type | Hoisted? | Initial Value | Usable Before Declaration? |
---|---|---|---|
var | Yes | undefined | Yes, but gives undefined |
let | Yes | Uninitialized | No (Temporal Dead Zone) |
const | Yes | Uninitialized | No (Temporal Dead Zone) |
Function Declaration | Yes | Function Body | Yes |
Function Expression | Variable Hoisted | undefined | No |
Best Practices:
- Prefer using
let
andconst
overvar
. - Always declare variables at the top of their scope to avoid confusion caused by hoisting.
- Understand TDZ when using
let
andconst
.