Variable Hoisting
Variable Hoisting
What is Hoisting?
JavaScript moves declarations to the top of their scope during compilation.
var Hoisting
console.log(x); // undefined (not error!)
var x = 10;
// Interpreter sees:
var x; // Declaration hoisted
console.log(x); // undefined
x = 10; // Assignment stays
let/const Hoisting
console.log(y); // ReferenceError!
let y = 20;
// let/const are hoisted but not initialized
// They're in the Temporal Dead Zone
Hoisting Scope
// Global scope
console.log(a); // undefined
var a = 1;
function example() {
// Function scope
console.log(b); // undefined
var b = 2;
if (true) {
// Block scope
console.log(c); // ReferenceError!
let c = 3;
}
}
Hoisting Order
// 1. Function declarations (fully hoisted)
// 2. var declarations (hoisted, not initialized)
// 3. let/const declarations (hoisted, TDZ)
// 4. Function expressions/arrow functions
Common Hoisting Patterns
// Using hoisting for declarations
function checkAge() {
// Declare first, use later
let message;
if (age >= 18) {
message = 'Adult';
} else {
message = 'Minor';
}
return message;
}
Hoisting Gotchas
// var in blocks
if (true) {
console.log(x); // undefined
var x = 10;
}
console.log(x); // 10 (var ignores block!)
// Let/const in blocks
if (true) {
// console.log(y); // ReferenceError!
let y = 20;
}
// console.log(y); // ReferenceError!
Function Hoisting
Function Hoisting
Function Declarations are Fully Hoisted
// Call before declaration works!
greet(); // "Hello!"
function greet() {
console.log('Hello!');
}
Function Expressions are NOT Hoisted
// Error!
sayGoodbye();
var sayGoodbye = function() {
console.log('Goodbye!');
};
// var is hoisted, but assignment is not
// sayGoodbye is undefined, not a function
Arrow Functions are NOT Hoisted
// Error!
multiply(2, 3);
const multiply = (a, b) => a * b;
Hoisting Priority
// Function declarations override var
var x = 1;
function x() {
return 2;
}
console.log(x); // 1 (assignment wins)
// But before assignment:
console.log(x); // function x() { return 2; }
Named Function Expressions
// Name is only accessible inside
const factorial = function fact(n) {
if (n <= 1) return 1;
return n * fact(n - 1);
};
// fact is not accessible outside
Class Declarations are NOT Hoisted
// Error!
const obj = new MyClass();
class MyClass {
constructor() {
this.name = 'John';
}
}
Temporal Dead Zone
Temporal Dead Zone
What is TDZ?
The period between hoisting and declaration where let/const variables exist but can't be accessed.
{
// TDZ starts here
// console.log(x); // ReferenceError!
let x = 10; // TDZ ends here
console.log(x); // 10
}
TDZ vs var
// var: no TDZ, returns undefined
console.log(a); // undefined
var a = 5;
// let/const: TDZ, throws error
// console.log(b); // ReferenceError!
let b = 10;
TDZ in Loops
// TDZ creates proper loop closure
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000);
}
// Output: 0, 1, 2 (not 3, 3, 3)
TDZ in Functions
function example() {
// TDZ for parameters
// console.log(x); // ReferenceError!
return x;
let x = 10;
}
example(); // ReferenceError!
TDZ with typeof
// typeof is safe with undeclared variables
console.log(typeof undeclared); // "undefined"
// But not with TDZ
{
// console.log(typeof x); // ReferenceError!
let x = 10;
}
Why TDZ Exists
// Prevents using uninitialized variables
let result = double(5);
function double(x) {
return x * 2;
// This would be bad if we could use 'result' here
}
TDZ and Closures
// TDZ creates proper closures in loops
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000); // 3, 3, 3
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 1000); // 0, 1, 2
}
Practice Problems
Create a reusable React component implementing Hoisting. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Hoisting using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Hoisting for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What is hoisting?
2. What happens when you access a var before declaration?
3. What happens when you access let before declaration?
4. What is the Temporal Dead Zone?
5. Are function expressions hoisted?
Flashcards
Question
What is hoisting?
Click to reveal answer
Answer
JavaScript moves declarations to the top of their scope during compilation.
Question
What is the difference between var and let/const hoisting?
Click to reveal answer
Answer
var is hoisted and initialized as undefined. let/const are hoisted but not initialized (TDZ).
Question
What is the Temporal Dead Zone?
Click to reveal answer
Answer
The period between hoisting and declaration where let/const variables exist but can't be accessed.
Question
Are function declarations hoisted?
Click to reveal answer
Answer
Yes, fully. You can call them before they're declared.
Question
Are arrow functions hoisted?
Click to reveal answer
Answer
No, only the variable is hoisted. The assignment happens at runtime.
Revision Notes
Key Takeaways
- 1.Hoisting moves declarations to the top of scope
- 2.var is hoisted and initialized as undefined
- 3.let/const are hoisted but in the TDZ
- 4.Function declarations are fully hoisted
- 5.TDZ prevents using uninitialized variables
Interview Tips
- •Explain what hoisting is and how it works
- •Know the difference between var and let/const hoisting
- •Understand the Temporal Dead Zone
- •Be able to predict the output of hoisting-related code
Cheat Sheet
Hoisting Cheat Sheet
var Hoisting
console.log(x); // undefined
var x = 10;
// Interpreter sees: var x; console.log(x); x = 10;
let/const Hoisting
// console.log(y); // ReferenceError!
let y = 20;
// Hoisted but in TDZ
Function Hoisting
greet(); // Works!
function greet() { console.log('Hi'); }
// sayHi(); // Error!
const sayHi = () => console.log('Hi');
TDZ
{
// TDZ: can't access
let x = 10; // Declaration
// Accessible here
}
Priority
- Function declarations
- var declarations
- let/const declarations