var vs let vs const
The one-card comparison.
var— function scope, hoisted asundefined, onwindow, re-declare ✓, re-assign ✓.let— block scope, hoisted into TDZ, Script scope (not on window), re-declare ✗, re-assign ✓.const— block scope, hoisted into TDZ, Script scope, re-declare ✗, re-assign ✗, must init at declaration.- Rule of thumb:
const>let> avoidvar.
The Temporal Dead Zone
Hoisted, but unreachable.
- TDZ = period from scope entry until the
let/constdeclaration line runs. - Any access inside TDZ throws
ReferenceError: Cannot access 'x' before initialization. - The message itself proves
let/constARE hoisted — if not, error would say is not defined. - Even
typeof xthrows in TDZ — unlike undeclared variables, wheretypeofsafely returns"undefined". - Shrink TDZ to zero: declare + initialize at the top of each scope.
Memory spaces
Where each declaration actually lives.
- Global — where top-level
varlives, attached towindow. - Script — where top-level
let/constlive, NOT onwindow. - Block — where block-level
let/constlive; destroyed when the{ }closes. - Local — function’s own memory. DevTools’ Scope panel shows all four separately.
const is not immutable
The binding is frozen, not the value.
constprevents reassigning the binding, not mutating the object.const obj = { a: 1 }; obj.a = 2;→ fine.obj = {}→ TypeError.const arr = [1,2]; arr.push(3);→ fine.arr = [4]→ TypeError.- For true immutability use
Object.freeze()— and remember it’s shallow.
Block scope & shadowing
Why var and let behave so differently.
let/constin{ }create a new Block-scope binding — outer variable untouched.varin{ }is the same variable as outer — block assignment overwrites global memory.- Illegal shadowing:
let a = …; { var a = …; }→ SyntaxError (var tries to live in the same scope). - Legal:
varshadowingletinside a function (function scope boundary isolates it).
Three error types
Which error fires at which stage.
- SyntaxError — code never runs. Duplicate
let, missingconstinitializer. - ReferenceError — runtime. TDZ access, or reading an undeclared identifier.
- TypeError — runtime. Reassigning a
const, callingundefined(). var+setTimeoutloop → all callbacks see finali; swap tolet→ each iteration gets its own.
Comments
Comments are disabled in this environment. Set
PUBLIC_GISCUS_REPO,PUBLIC_GISCUS_REPO_ID, andPUBLIC_GISCUS_CATEGORY_IDto enable.