Q5 of 40 · JavaScript
What is hoisting in JavaScript, and how does it affect `var`, `let`, and `const`?
Short answer
Short answer: Hoisting moves `var` declarations and function declarations to the top of their scope before execution. `var` is initialized as `undefined`; `let` and `const` are hoisted but inaccessible until their line (temporal dead zone), throwing ReferenceError if accessed early.
Detail
Hoisting is the runtime behaviour where declarations are processed before any code executes in their scope.
var hoisting: The declaration is moved to the top of the function scope and initialized to undefined. Accessing a var before its assignment returns undefined rather than throwing — a silent bug source.
Function declaration hoisting: Entire function bodies are hoisted, which is why you can call a declared function before its definition in the file. Function expressions (const fn = function() {}) are not fully hoisted — only the variable declaration is.
let and const hoisting: Both are hoisted to the block scope but are not initialized. The region between the start of the block and the variable's declaration is the temporal dead zone. Accessing the variable there throws a ReferenceError, making bugs visible immediately — this is why let and const are safer.
In test code, hoisting matters when you share setup variables across beforeEach and test blocks. With var, accessing a variable before setup runs silently gives undefined. With let/const it throws, making the problem obvious.
// EXAMPLE
// var hoisting — silent undefined
console.log(x); // undefined, not ReferenceError
var x = 5;
// let — temporal dead zone
// console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 5;
// Function declaration — fully hoisted
greet(); // works fine
function greet() { console.log("hello"); }
// Function expression — not fully hoisted
// sayBye(); // TypeError: sayBye is not a function
const sayBye = () => console.log("bye");