{"post":{"slug":"what-is-hoisting-in-javascript-2026","title":"What is hoisting in JavaScript in 2026? var, let, and const","excerpt":"Hoisting moves variable and function declarations to the top of their scope before code runs. Here is how var, let, const, and functions actually behave.","category":"code","date":"July 23, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">H</span>oisting is the behavior where JavaScript processes variable and function declarations before running the rest of a scope's code. It looks like the declaration moved to the top, which is where the name comes from, but nothing actually moves. The engine scans a scope before executing it and registers the names it finds, and what happens if you reference one of those names early depends entirely on how it was declared.\n\n## What changed in 2026\n\n- **Linting defaults catch most hoisting bugs before they ship.** ESLint's recommended configuration and most 2026 starter templates, including Vite and Next.js defaults, enable rules against `var` and against using a name before its definition, so many hoisting surprises never reach production.\n- **Editors flag temporal dead zone violations while typing.** TypeScript's control-flow analysis and strict mode catch most early-access bugs at compile time, turning what used to be a runtime surprise into a red underline in the editor.\n- **A new generation of developers meets the temporal dead zone before the var quirk.** AI assistants almost always generate `let` and `const`, rarely `var`, so newer developers often encounter the temporal dead zone first and the classic var-returns-undefined behavior later, usually while reading legacy code.\n\n## What actually gets hoisted\n\n```js\nconsole.log(x); // undefined, not an error\nvar x = 5;\n\nconsole.log(y); // ReferenceError: Cannot access 'y' before initialization\nlet y = 5;\n```\n\nBoth `x` and `y` are registered during the setup pass. `var` gets an initial value of `undefined` immediately, so reading it early just returns that. `let` and `y` exist too, but sit in a state where reading them throws instead.\n\n## var, let, const, and function declarations compared\n\n| Declaration | Hoisted? | Value before its line | Error if accessed early? |\n| --- | --- | --- | --- |\n| `var` | Yes | `undefined` | No |\n| `let` / `const` | Yes, name only | Not accessible (temporal dead zone) | Yes, reference error |\n| `function foo() {}` | Yes, fully, with body | Callable | No |\n| `const foo = () => {}` | Name only, not the value | Not accessible | Yes, reference error |\n\n## The temporal dead zone\n\nThe temporal dead zone is the span between the start of a scope and the line where a `let` or `const` variable is actually declared. During that span, the variable exists, which is why it can shadow an outer variable of the same name, but it cannot be read or written.\n\n```js\nlet value = \"outer\";\nfunction demo() {\n  console.log(value); // ReferenceError, not \"outer\"\n  let value = \"inner\"; // temporal dead zone ends here\n}\ndemo();\n```\n\nEven though an outer `value` exists, the inner `let value` shadows it for the entire function, including before its own declaration line, which is exactly why this throws instead of logging \"outer.\"\n\n## Function declarations vs function expressions\n\n```js\nsayHi(); // works: \"Hi!\" — full function is hoisted\nfunction sayHi() { console.log(\"Hi!\"); }\n\nsayBye(); // TypeError: sayBye is not a function\nvar sayBye = function () { console.log(\"Bye!\"); };\n```\n\nOnly the declaration form is hoisted along with its body. A function expression assigned to a variable follows that variable's own hoisting rules: the variable name is hoisted, but the function assigned to it is not available until that line actually runs.\n\n## Why this matters day to day\n\nRecognizing the temporal dead zone turns a \"cannot access before initialization\" error from a mystery into a two-second fix, instead of a suspected import or scope problem. Relying on function-declaration hoisting to call a helper before its definition works, but it hurts readability, and most style guides ask you to define things before use anyway. Mixing `var` and `let` in the same file makes hoisting behavior inconsistent within one scope; sticking to `let` and `const` removes an entire category of surprise. It also affects closures directly: see [what a closure is in JavaScript](/blog/what-is-a-closure-in-javascript-2026) for why a `var` inside a loop is captured differently than a `let`.\n\n## FAQ\n\n**Does hoisting mean my code actually gets reordered?**\nNo. Nothing moves. The engine registers declared names during a setup pass before executing the scope, which looks like reordering from the outside, but the source code is untouched.\n\n**Why does let throw an error instead of just returning undefined like var?**\nIt is a deliberate design choice from ES2015, meant to catch a category of bugs early. Reading a variable before its declaration line is almost always a mistake, so `let` and `const` fail loudly instead of silently.\n\n**Are class declarations hoisted?**\nThe name is hoisted like `let`, into the temporal dead zone. A class cannot be constructed before its declaration line, even though the name technically exists earlier in the scope.\n\n**Is hoisting a JavaScript-only concept?**\nThe term is most associated with JavaScript, but similar declaration-before-execution behavior appears in other languages under different names.\n\n## Where to go next\n\n- [What is a closure in JavaScript in 2026](/blog/what-is-a-closure-in-javascript-2026)\n- [What is the event loop in 2026](/blog/what-is-the-event-loop-2026)\n- [Callbacks vs promises vs async await in 2026](/blog/callbacks-vs-promises-vs-async-await-2026)","hue":260,"metaTitle":"What Is Hoisting in JavaScript 2026?","metaDescription":"What is hoisting in JavaScript in 2026? How var, let, const, and function declarations are hoisted differently, with the temporal dead zone explained.","keywords":["hoisting in javascript 2026","what is hoisting","var vs let hoisting","temporal dead zone explained","function hoisting javascript","javascript hoisting example","let const hoisting","hoisting interview question","javascript variable declarations","hoisting best practices"],"tldr":["**Declarations are processed before any code runs, but initializers are not** — the name exists early; the value does not show up until the original line executes.","**var is hoisted and initialized to undefined** — referencing it before its line does not error, it just returns undefined.","**let and const are hoisted but stay in the temporal dead zone** — referencing them before their line throws a reference error instead of returning undefined.","**Function declarations are hoisted completely, including the body** — a function declared with the function keyword can be called before the line it appears on.","**Skip:** relying on hoisting on purpose; write declarations before use regardless of what the language allows, since hoisting is a rule to understand, not a style to write with."],"readTime":"4 min read","wordCount":850},"related":[{"slug":"what-is-the-event-loop-2026","title":"What is the event loop in 2026? Tracing code step by step","excerpt":"The event loop decides what runs next when your code has a call stack, a microtask queue, and a callback queue all waiting. Here is how to trace it.","category":"code","date":"July 24, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":290},{"slug":"what-is-the-single-responsibility-principle-2026","title":"What is the single responsibility principle in 2026?","excerpt":"The single responsibility principle says a class or module should have one reason to change. Here is what that means in practice and where it gets misapplied.","category":"code","date":"July 24, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":280},{"slug":"what-is-a-closure-in-javascript-2026","title":"What is a closure in JavaScript in 2026? Plain-English guide","excerpt":"A closure is a function that remembers the variables from where it was created, even after that outer code has finished running. Here is what that enables.","category":"code","date":"July 17, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":240}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"workers-comp-guide-2026","title":"Workers Compensation: Reporting an Injury Correctly","excerpt":"A workplace injury claim turns on prompt reporting and documentation. Here is the sequence and the mistakes that cost people benefits.","category":"guides","date":"July 24, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":45},"older":{"slug":"what-is-immutability-in-code-2026","title":"What Is Immutability in Code? 2026 Guide","excerpt":"Immutability means a value cannot change after it is created — any update produces a new value instead. Here is what that buys you, what it costs, and where the common gotchas hide.","category":"code","date":"July 23, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":310}}