Free lesson · JavaScript Basic to Advance
Interview Lens: Scope and Hoisting
The Question
Three questions, often asked together, sometimes split across multiple rounds:
"What's the difference between
var,let, andconst?""Can you explain hoisting?"
"What's the output of this code?" — followed by some code with declarations before their first use, often with
setTimeoutinvolved for extra spice.
This is the variables-and-scope battery. It appears in nearly every JavaScript-focused interview, from new-grad screens at startups to senior loops at FAANG. Some interviewers ask all three. Some pick one and probe deep. Either way, you need to be ready.
Arun and Nikhil co-authoring this one. Arun on the interview pattern and the recovery strategies — he has the freshest memory of being on the other side of these questions, with 14 rejections before Apple. Nikhil on the technical depth — when an interviewer pushes into execution-context territory, you want his framing.
Why They Ask It
Variables and scope are the foundation. If a candidate can't talk about how variables work in JavaScript, no deeper question — closures, async, prototypes — will produce a meaningful answer. So interviewers use this as the first gate.
Three signals they're listening for:
Signal 1: Do you know modern JavaScript, or are you stuck in 2010? A candidate who reaches for var first, who can't articulate why let and const exist, who doesn't mention block scoping — that candidate has been learning JavaScript from outdated tutorials. Real production codebases haven't used var as the default in nearly a decade.
Signal 2: Do you understand the mechanism, or just the rules? A candidate who can recite "var is function-scoped, let is block-scoped" has memorized a fact. A candidate who can explain why let was added, what problem it solves, how the engine processes declarations during the creation phase — that candidate understands the language.
Signal 3: Can you handle pressure on a question you "know"? Hoisting is a topic everyone studies. Interviewers know you've studied it. They ask anyway, because watching how you handle a question you've prepared for tells them how you'll handle one you haven't.
I (Arun) bombed my fifth interview on a hoisting question I had absolutely studied. The interviewer wrote a five-line snippet on the whiteboard and asked me to predict the output. I knew the rules. I knew them cold the day before. But under pressure, with someone watching, I tried to trace the code in my head all at once instead of step by step. I got the wrong answer. The interviewer's face told me everything before he said anything.
What I learned: don't trace mentally. Trace out loud, step by step, like a teacher explaining it to a student. The verbal pace forces you to slow down enough to actually think.
Interactive animation: Four passes over the snippet, in order - a way to trace step by step instead of all at once.
The Wrong Answers
Warning: The wrong answers interviewers hear repeatedly.
"
varis older,letandconstare newer. Use whichever." This signals the candidate doesn't know whyletandconstexist. The right framing:letandconstfix specific problems withvar— function scoping that leaked variables, hoisting that gaveundefinedsilently, redeclaration that hid typos. They aren't "newer." They're "better, on purpose.""Hoisting means JavaScript moves all declarations to the top of the file." This is the metaphor used in tutorials, but it's wrong as a mechanism. JavaScript doesn't physically move code. The engine processes declarations during the creation phase, before execution starts. The behavior is as if declarations were moved up, but the source code stays where you wrote it. Using the metaphor as the definition signals you've heard the buzzword but don't understand the mechanism.
"
letandconstaren't hoisted." This is the most common wrong answer of all. They are hoisted. The difference is that they're in the Temporal Dead Zone until the declaration line — they exist but can't be accessed. Saying they're "not hoisted" suggests you haven't studied the spec, just the surface behavior.
The Right Answer
Three layers, depending on how much the interviewer wants to hear.
The 30-Second Answer
When the interviewer is checking a box and wants to move on:
"var is function-scoped and allows redeclaration. let and const are block-scoped and don't allow redeclaration in the same block. const additionally prevents reassignment of the variable, though it doesn't make objects or arrays immutable. All four — function declarations, var, let, and const — are hoisted, but let and const are in a Temporal Dead Zone until their declaration line is reached, so accessing them too early throws a ReferenceError instead of giving you undefined."
That's enough for a screen or a warm-up. Stop here unless they push.
The 2-Minute Answer
When they want to see your reasoning, build on the 30-second answer:
"The reason let and const were added in ES6 is to fix specific problems with var. Function scoping caused variables to leak out of blocks where they were declared — loop counters being accessible throughout the rest of the function, variables in if blocks being visible afterward, that kind of thing. Block scoping with let and const keeps variables inside the braces they were declared in.
The hoisting differences are about safety. With var, reading a variable before its declaration gives you undefined with no error. If your logic depended on the variable having a specific value, you get silently wrong behavior. With let and const, the same code throws a ReferenceError. The error is the feature — it forces the bug to surface immediately instead of hiding.
For new code, the modern style is: use const by default, switch to let when you need to reassign, and avoid var entirely. This rules out an entire class of scope-related bugs without any cost."
This is the answer for a standard onsite when they want depth.
Interactive animation: The leaking block, step by step - a var declared in an if is still readable afterwards, a let is not.
The Deep Dive
When the interviewer probes further, especially at senior or staff levels (this is Nikhil's section):
Build on the 2-minute answer. Then add:
"At the engine level, hoisting is part of how execution contexts are constructed. When the engine enters a function or block, it runs a creation phase before executing your code. During that phase, it scans for declarations and registers them in the variable environment.
Function declarations get registered with their full definitions — that's why you can call them before their declaration line. var declarations get registered with the name and initialized to undefined — that's why reading them early returns undefined. let and const declarations get registered with the name but left in an uninitialized state — that's the Temporal Dead Zone. Reading them in this state throws because the engine specifically flags them as not yet ready.
The TDZ has subtle behaviors worth knowing. typeof on an undeclared variable returns "undefined" without throwing, but typeof on a let or const variable in its TDZ does throw. That's because for let and const, the variable exists in the scope — it's just not accessible yet — so the typeof operator can't pretend it doesn't exist.
In senior-level interviews, the question often goes deeper than 'what is hoisting' into 'how does the engine implement it.' The answer is: it's the creation phase of the execution context, defined in the ECMAScript specification, where the engine prepares the variable environment before running any of your code."
This level signals real depth. Use it when the interview is at a level where execution-model questions are being probed.
Interactive animation: Used before declared, traced per keyword - var gives undefined, let and const throw, a function declaration works.
The Whiteboard Examples Interviewers Use
Two examples come up so often they're worth treating like standard interview material.
Example 1 — Hoisting prediction:
console.log(a);
console.log(b);
console.log(c);
var a = 1;
let b = 2;
const c = 3;
Walk through it out loud: "Line 1 is console.log(a). a is declared with var later, so it's hoisted and initialized to undefined. This logs undefined. Line 2 is console.log(b). b is declared with let later, so it's hoisted but in the TDZ. This throws a ReferenceError. The function stops here."
If you trace it out loud like that, the interviewer sees that you're reasoning from the rules, not guessing.
Example 2 — The for-loop classic:
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
Walk through it: "var i is function-scoped, so there's only one i shared across all iterations. The loop runs to completion synchronously, setting up three timer callbacks. By the time those callbacks fire, i has already reached 3. All three callbacks read the same i, so all three log 3."
The fix is one keyword: change var to let. With let, each iteration creates a new i in its own block scope. The three callbacks each capture their own i, so they log 0, 1, 2.
If you can walk through this example and the fix without hesitation, you've signaled mastery of both scope and the async execution model.
Interactive animation: The for-loop classic - a shared var i logs 3 three times, a fresh let i logs 0, 1, 2.
The Follow-Ups
Interview: What the interviewer asks next once you've answered well.
"Why was
letadded when JavaScript already hadvar?" They want to hear about the specific problemsvarcaused — function scoping leaking variables, silentundefinedon early access, redeclaration hiding bugs — and howletsolves each."What's the difference between hoisting
varand hoistinglet?" Both are hoisted.varis initialized toundefined.letis in the TDZ until the declaration line."Can you reassign a
constarray?" No, but you can mutate it.const arr = [1,2]; arr.push(3)works.const arr = [1,2]; arr = [4,5]throws. The distinction is between the variable binding and the value it points to."What is the Temporal Dead Zone, and what's its purpose?" The period between block start and declaration line where a
letorconstvariable exists but can't be accessed. Its purpose is to prevent the silentundefinedbugs thatvarallows."Can you make an object truly immutable?" Beyond
const. MentionObject.freeze()for shallow immutability and the concept of deep freezing for nested objects.
The Founder Moment
Nikhil here. The hoisting question came up in my second Google interview — the one I failed on system design. I got the hoisting question early, in the coding round, and I aced it. I walked through the creation phase, the TDZ, the difference between function declarations and function expressions. The interviewer nodded, and I felt the room shift in my favor.
Three rounds later I bombed the system design and didn't get the offer. But the hoisting moment taught me something I carried forward: when an interviewer asks a question you've prepared for, your job isn't to recite the answer. Your job is to demonstrate the thinking that produces the answer.
Anyone can memorize "var is function-scoped, let is block-scoped." That gets you to "this candidate has read tutorials." What gets you to "this candidate understands JavaScript" is being able to construct the answer in front of the interviewer, in your own words, traced through the actual mechanism.
Memorize the rules. Then practice explaining them out loud. The explanation is what the interviewer is grading, not the answer itself.