Declaration order flexibility
Place function declarations below the code that calls them when organizing small scripts or modules.
JS Puzzles · Const
Hoisting is the observable behavior in which JavaScript makes certain declarations available before their source position executes. Its effects differ: var reads as undefined, function declarations are callable, and let/const remain inaccessible in the temporal dead zone.
JavaScript processes declarations before executing code in their scope, but the result differs by declaration type. A var binding is available early with the value undefined until its assignment runs, whereas a function declaration is callable with its body already available. let, const, and class bindings occupy their block scope but remain inaccessible in the temporal dead zone until execution reaches their declaration.
var binding is established before statements in its script run.var name above its declaration is syntactically allowed, although its value may not yet be assigned.var, the assignment portion takes effect at its original execution point rather than at the start of the scope.let access is delayed until execution reaches its declaration.var declaration being available early does not move its assigned value early; before the assignment executes, reading it produces undefined.let or const binding before its declaration executes throws a ReferenceError, rather than returning undefined.function beforeDeclaration() {
console.log(value); // undefined
var value = 42;
return value;
}
function declarationCall() {
return greet();
function greet() {
return "hello";
}
}
console.log(beforeDeclaration());
console.log(declarationCall());The var binding exists before execution reaches its assignment, while the function declaration can be called before its source position.
Place function declarations below the code that calls them when organizing small scripts or modules.
Use hoisting rules to diagnose why an early var read returns undefined instead of the assigned value.
Recognize temporal-dead-zone errors when refactoring function or block scope to let or const.
var and function declarations differ?Hoisting describes the observable effect that declarations are processed before normal execution in their scope. var can therefore be read before its source line, but it has the value undefined until initialization; function declarations can be called before their source line.
Follow-up: What happens with const? Its binding exists for the block, but access before the declaration reaches initialization is blocked by the temporal dead zone and throws ReferenceError.
let or const before its declaration throw?A let or const declaration is block-scoped and cannot be accessed before execution reaches its declaration. During that interval it is in the temporal dead zone, so an access produces ReferenceError rather than undefined.
Follow-up: Why can an outer variable not be used as a fallback inside the block? The inner lexical declaration occupies the relevant scope, so the early access resolves to the uninitialized inner binding.
Function declaration hoisting makes the declared function available throughout its enclosing function or global scope, including before the declaration appears. Function expressions do not receive this behavior because the variable is assigned only when execution reaches the expression.
Follow-up: How could the behavior be made available earlier? Use a function declaration, or place the function-expression assignment before its first call.
var declarationslet declarationsconst declarationsfunction declarationsfunction expressionsclass declarationstemporal dead zone