← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Hoisting — var, let, const and function

javascript ES5 Intermediate
debt(d3/e1/b3/t7)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3). ESLint (listed in detection_hints.tools) has rules like no-var, no-use-before-define, and prefer-const that catch the most common hoisting mistakes. TypeScript also catches TDZ violations at compile time. These are mainstream tools that catch the common cases without specialist configuration.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix is explicit: replace var with const/let throughout. This is a mechanical, largely automated substitution (ESLint --fix can handle many cases). Switching to arrow functions from hoisted function declarations is similarly local. No cross-file architectural changes needed.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The concept applies to web and cli contexts broadly, but once a codebase adopts const/let as a standard (which is now idiomatic JS), the ongoing burden is low. Legacy codebases using var everywhere carry a persistent but localized tax within affected files. It does not reshape architecture or slow many work streams.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field identifies the canonical trap: developers believe let/const are not hoisted at all, when they ARE hoisted but placed in the Temporal Dead Zone, causing a ReferenceError instead of the expected undefined. This contradicts the intuition from var behavior and from how similarly-named constructs in other languages behave. The arrow-function-not-hoisted gotcha adds another layer of contradiction for devs familiar with function declarations.

About DEBT scoring →

Also Known As

variable hoisting function hoisting TDZ

TL;DR

JavaScript hoists declarations to the top of their scope — var and function declarations are fully hoisted, while let and const are hoisted but remain in the Temporal Dead Zone until their declaration line.

Explanation

Function declarations are fully hoisted: you can call a function before its declaration. var declarations are hoisted but initialised to undefined — accessing before assignment gives undefined, not an error. let and const are technically hoisted to block scope but live in the Temporal Dead Zone (TDZ) until their declaration — accessing them before declaration throws a ReferenceError. PHP has no hoisting — functions and variables must be declared before use.

Common Misconception

let and const are not hoisted — they are hoisted to block scope but placed in the Temporal Dead Zone, so accessing them before declaration throws a ReferenceError rather than returning undefined.

Why It Matters

Hoisting explains why function declarations work anywhere in a file, why var can be used before assignment returning undefined silently, and why let/const are safer.

Common Mistakes

  • Using var inside a loop expecting block scope (it has function scope)
  • Accessing a let variable before declaration expecting undefined
  • Relying on function hoisting then switching to arrow functions (not hoisted)

Code Examples

✗ Vulnerable
console.log(x); // undefined (not ReferenceError)
var x = 5;

foo(); // Works — function declarations are fully hoisted
function foo() { console.log('hello'); }

bar(); // TypeError: bar is not a function
var bar = function() {};
✓ Fixed
// Avoid hoisting confusion — declare before use:
const x = 5;
console.log(x);

// Function declarations are fine to call before definition
// but prefer declaring at top for clarity

// Always use const/let — no hoisting surprises:
const bar = () => {};
bar();

Added 22 Mar 2026
Edited 23 Mar 2026
Views 27
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 9 Google 3 Perplexity 3 Ahrefs 3 Unknown AI 3 Majestic 1
crawler 20 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Use const by default and let when reassignment is needed — never var. This eliminates hoisting surprises since const/let have block scope and TDZ protection
📦 Applies To
javascript ES5 web cli
🔗 Prerequisites
🔍 Detection Hints
var declarations inside loops or if blocks; function called before its declaration; accessing variable before let/const declaration line
Auto-detectable: ✓ Yes eslint typescript
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✓ Auto-fixable Fix: Low Context: Function

✓ schema.org compliant