Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

Hoisting & The Temporal Dead Zone: Why `let` and `const` Behave Differently Than `var`

You've probably seen this error before: ReferenceError: Cannot access 'myVariable' before initialization Or wondered why this works: console.log(x); // undefined (not an error!) var x = 5; But this…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

You've probably seen this error before:




ReferenceError: Cannot access 'myVariable' before initialization






Or wondered why this works:




console.log(x); // undefined (not an error!)
var x = 5;






But this doesn't:




console.log(y); // ReferenceError!
let y = 5;






The answer lies in hoisting and the Temporal Dead Zone (TDZ) — two of JavaScript's most misunderstood features.






The Golden Rule



All declarations (var, let, const, function, class) are hoisted to the top of their scope during the compilation phase, but only var and function declarations are initialized. let and const remain in the Temporal Dead Zone until their declaration is executed.



In simpler terms: JavaScript knows about your variables before you declare them, but let and const can't be accessed until the exact line where they're declared.



Let's break this down step by step.









Part 1: What is Hoisting?



JavaScript runs in two phases:




  1. Compilation Phase — Code is parsed, variables are registered, scope is determined

  2. Execution Phase — Code runs line by line



Hoisting is what happens during the compilation phase: JavaScript moves declarations to the top of their scope (conceptually — it doesn't literally move code).









Function Hoisting






greet(); // "Hello!" (works!)

function greet() {
console.log('Hello!');
}






Why this works:




  • The entire function is hoisted (both declaration and body)

  • You can call it before the line where it's defined



What JavaScript "sees":




function greet() { // Hoisted to top
console.log('Hello!');
}

greet(); // Now it makes sense












Function Expressions Are NOT Hoisted






greet(); // TypeError: greet is not a function

var greet = function() {
console.log('Hello!');
};






Why this fails:





  • var greet is hoisted (as undefined)

  • But the function assignment happens later

  • You're trying to call undefined(), which is an error



What JavaScript "sees":




var greet; // Hoisted, initialized to undefined
greet(); // Calling undefined()

greet = function() {
console.log('Hello!');
};












Part 2: var Hoisting






Variables Declared with var






console.log(x); // undefined (not an error!)
var x = 5;
console.log(x); // 5






What JavaScript "sees":




var x; // Hoisted and initialized to undefined
console.log(x); // undefined
x = 5; // Assignment happens here
console.log(x); // 5






Key Points:





  • var declarations are hoisted to the top of their function scope (or global scope)

  • They're initialized to undefined

  • The assignment stays where it is









var is Function-Scoped, Not Block-Scoped






function example() {
if (true) {
var x = 5;
}
console.log(x); // 5 (accessible outside the block!)
}

example();






What JavaScript "sees":




function example() {
var x; // Hoisted to function scope
if (true) {
x = 5;
}
console.log(x); // 5
}






Problem: var ignores block scope (if, for, while), which leads to unexpected behavior:




for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Logs: 3, 3, 3 (all callbacks see the same 'i')












Part 3: let and const Hoisting



Here's the twist: let and const are hoisted, but they're not initialized.






The Temporal Dead Zone (TDZ)






console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 5;






What's happening:





  • let x is hoisted to the top of the block scope

  • But it's not initialized (no default value)

  • The time between the start of the block and the let x declaration is the Temporal Dead Zone

  • Accessing x in the TDZ throws a ReferenceError









Visualizing the TDZ






{
// TDZ starts here for 'x'
console.log(x); // ReferenceError
// TDZ continues...
// TDZ ends here
let x = 5; // 'x' is now initialized
console.log(x); // 5
}






The TDZ is temporal (time-based), not spatial (location-based):




{
const func = () => console.log(x); // Defined before 'x'
let x = 5;
func(); // Works! (called after 'x' is initialized)
}












const Has the Same Behavior






console.log(y); // ReferenceError
const y = 10;






Additional const rule: Must be initialized at declaration:




const z; // SyntaxError: Missing initializer in const declaration












Part 4: var vs let vs const






Comparison Table


















































Feature var let const
Scope Function-scoped Block-scoped Block-scoped
Hoisting Yes (initialized to undefined) Yes (but uninitialized) Yes (but uninitialized)
TDZ No Yes Yes
Re-declaration Allowed Not allowed Not allowed
Reassignment Allowed Allowed Not allowed
Initialization Required No No Yes








Re-declaration Examples



var allows re-declaration:




var x = 1;
var x = 2; // No error
console.log(x); // 2






let doesn't:




let y = 1;
let y = 2; // SyntaxError: Identifier 'y' has already been declared






const doesn't:




const z = 1;
const z = 2; // SyntaxError: Identifier 'z' has already been declared












Reassignment Examples






let x = 1;
x = 2; // Allowed

const y = 1;
y = 2; // TypeError: Assignment to constant variable






Important: const prevents reassignment, not mutation:




const obj = { name: 'Alice' };
obj.name = 'Bob'; // Mutation allowed
obj = {}; // Reassignment forbidden












Part 5: Block Scoping in Practice






let in Loops






for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Logs: 0, 1, 2 (each callback has its own 'i')






Why this works: let creates a new binding for each iteration.



Compare to var:




for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Logs: 3, 3, 3 (all callbacks share the same 'i')












let in if Blocks






if (true) {
let blockScoped = 'Inside';
console.log(blockScoped); // "Inside"
}

console.log(blockScoped); // ReferenceError: blockScoped is not defined






With var:




if (true) {
var functionScoped = 'Inside';
console.log(functionScoped); // "Inside"
}

console.log(functionScoped); // "Inside" (leaked out of block!)












Part 6: Hoisting in React



While modern React doesn't rely heavily on hoisting quirks, understanding it helps avoid bugs.






1. Component Definition Order



Function declarations are hoisted:




function App() {
return <Header />; // Works
}

function Header() {
return <h1>Hello</h1>;
}






Function expressions are not:




function App() {
return <Header />; // ReferenceError (or undefined)
}

const Header = () => {
return <h1>Hello</h1>;
};






Fix: Define components before using them, or use function declarations.









2. useState and Hoisting






function Counter() {
console.log(count); // ReferenceError! (TDZ)

const [count, setCount] = useState(0);

return <div>{count}</div>;
}






Why this fails: const is in the TDZ before its declaration.



This is fine:




function Counter() {
const [count, setCount] = useState(0);

console.log(count); // 0

return <div>{count}</div>;
}












3. Closure Issues with var in React



Old pattern (before hooks):




class Counter extends React.Component {
state = { count: 0 };

componentDidMount() {
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i); // Logs: 3, 3, 3
}, i * 1000);
}
}

render() {
return <div>{this.state.count}</div>;
}
}






Fix with let:




for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i); // Logs: 0, 1, 2
}, i * 1000);
}












4. Event Handlers and Block Scope






function Form() {
const [value, setValue] = useState('');

const handleSubmit = (e) => {
e.preventDefault();

if (value) {
const message = `Submitted: ${value}`; // Block-scoped
alert(message);
}

// console.log(message); // ReferenceError (outside block)
};

return (
<form onSubmit={handleSubmit}>
<input value={value} onChange={(e) => setValue(e.target.value)} />
<button>Submit</button>
</form>
);
}






Key Point: Block-scoped variables (let, const) are contained to their blocks, preventing accidental usage outside.









Part 7: Common Hoisting Gotchas






Gotcha 1: Function Declarations vs Expressions






// Function declaration (hoisted)
function sayHi() {
console.log('Hi!');
}

// Function expression (not hoisted)
const sayBye = function() {
console.log('Bye!');
};

// Arrow function (not hoisted)
const sayHello = () => {
console.log('Hello!');
};






Only function declarations are fully hoisted.









Gotcha 2: Class Hoisting



Classes are hoisted but remain in the TDZ like let and const:




const instance = new MyClass(); // ReferenceError

class MyClass {
constructor() {
this.value = 42;
}
}






Fix: Define classes before using them:




class MyClass {
constructor() {
this.value = 42;
}
}

const instance = new MyClass(); // Works












Gotcha 3: TDZ in Parameter Defaults






function example(a = b, b = 2) {
console.log(a, b);
}

example(); // ReferenceError: Cannot access 'b' before initialization






Why? When evaluating a = b, b is still in the TDZ (parameters are evaluated left-to-right).



Fix:




function example(b = 2, a = b) {
console.log(a, b);
}

example(); // 2, 2












Gotcha 4: typeof and TDZ



With var:




console.log(typeof x); // "undefined" (no error)
var x = 5;






With let:




console.log(typeof y); // ReferenceError (TDZ!)
let y = 5;






Surprising, right? Even typeof can't save you from the TDZ.









Gotcha 5: Accessing Variables from Outer Scope






let x = 'outer';

{
console.log(x); // ReferenceError
let x = 'inner';
}






Why? The inner let x is hoisted to the top of the block, creating a TDZ. JavaScript doesn't look at the outer x.



Fix: Don't shadow variables if you need the outer value:




let x = 'outer';

{
console.log(x); // "outer"
let y = 'inner'; // Different name
}












Quick Reference Cheat Sheet












































Scenario var let const
Accessed before declaration undefined ReferenceError (TDZ) ReferenceError (TDZ)
Scope Function Block Block
Re-declare in same scope Allowed Not allowed Not allowed
Reassign Allowed Allowed Not allowed
Mutate object properties N/A N/A Allowed








Key Takeaways



All declarations are hoisted, but only var and function declarations are initialized

let and const are in the TDZ from the start of the block until their declaration

Accessing a variable in the TDZ throws ReferenceError, not undefined

var is function-scoped; let and const are block-scoped

Use const by default, let when reassignment is needed, avoid var

const prevents reassignment, not mutation of objects/arrays

Classes are hoisted but remain in the TDZ like let and const









Interview Tip



When asked about hoisting, explain it clearly:




  1. "Hoisting is when JavaScript moves declarations to the top of their scope during compilation"

  2. Contrast var and let/const:



    • var is initialized to undefined


    • let and const remain uninitialized in the TDZ



  3. Explain TDZ: "The Temporal Dead Zone is the period between entering a scope and the variable's declaration where accessing it throws a ReferenceError"

  4. Best practice: "Use const by default, let when reassignment is needed, and avoid var to prevent scoping issues"

  5. React connection: "In React, block scoping with let and const prevents common closure bugs, especially in loops and event handlers"



Now go forth and never be confused by ReferenceError: Cannot access before initialization again!

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Vulnerability Remediation & Verification
Syntax validiert (0 Fehler)
title: Detect Exploitation - Hoisting & The Temporal Dead Zone: Why `let` and `const` Behave Differently Than `var`
id: 09d0ea07-882d-4fa2-92a8-c980e8ac9d23
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-25
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-25"
        description = "YARA Signature for "
    strings:
        $str = "Hoisting & The Temporal Dead Z" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("Hoisting  The Temporal Dead Zone Why let")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*Hoisting  The Temporal Dead Zone Why let*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "Hoisting  The Temporal Dead Zone Why let"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph2 Knoten / 1 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich Hoisting &amp; The Temporal Dead Zone: Why `.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Hoisting & The Temporal Dead Zone: Why `let` and `const` Behave Differently Than `var`

Thematisch verwandte Begriffe: Hoisting, Temporal, Dead, Zone · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-97875 | Rojo's "rojo serve" HTTP API (default port 34872) has no Host/Origin hea…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag