Interview questions

let vs var interview: the 60-second answer

August 1, 2025Updated May 15, 202616 min read
Can Understanding Let Vs Var Be The Secret Weapon For Acing Your Next Interview

A tight let vs var interview guide with a 30-second and 60-second answer, the real differences in scope and hoisting, and the follow-up traps interviewers use

Most candidates who stumble on let vs var interview questions aren't missing knowledge — they're missing a structure for delivering it. They know what block scope means. They've read about hoisting. But when the interviewer asks "what's the difference between let and var?" the answer that comes out is either a wall of jargon or a hesitant half-sentence that trails off into "...it's something to do with scope?" The problem isn't understanding. It's the gap between understanding something and being able to say it clearly under pressure, in sequence, without backtracking.

What follows is a speaking structure, not a lecture. The goal is a 30-second answer that holds up under follow-up questions — because that's what actually gets you through a technical screen.

Give the 30-second answer first, not the textbook

The instinct when asked a foundational question is to be thorough. Resist it. Interviewers asking about let vs var interview questions are not looking for a complete history of JavaScript's scoping model. They are checking whether you understand the practical difference well enough to explain it to a colleague. Start simple and let the follow-ups pull out the depth.

The answer you can actually say out loud

Here is a 30-second script you can use verbatim. Time it:

"The main difference is scope. `let` is block-scoped — it only exists inside the curly braces where it's declared. `var` is function-scoped, which means it's accessible anywhere within the function, even outside the block where you wrote it. `var` is also hoisted to the top of its scope and initialized as `undefined`, so you can reference it before the line where you declared it without getting an error — which is usually not what you want. `let` is hoisted too, but it stays in a temporal dead zone until the declaration runs, so accessing it early throws a ReferenceError. In practice, `let` is easier to reason about because it behaves closer to what you'd expect."

That's it. Under 30 seconds. It covers scope, hoisting, and the temporal dead zone in plain language. According to MDN Web Docs, this is precisely the distinction the specification draws — `let` declarations are block-scoped and subject to the temporal dead zone, while `var` declarations are function-scoped and initialized to `undefined` at the top of their scope.

What this sounds like when it lands

Contrast these two responses to "what's the difference between let and var?":

Weak: "So, `let` is like... more modern, and `var` has some issues with scoping. I think `var` gets hoisted, which means it goes to the top, and `let` doesn't do that the same way. You should use `let` because it's better."

Strong: "The main difference is scope. `let` is block-scoped, `var` is function-scoped. `var` gets hoisted and initialized as `undefined`, so you can access it before the declaration without an error — but that's usually a bug waiting to happen. `let` is hoisted too, but it stays in a dead zone until initialization, so it throws if you try to access it early. That makes `let` safer for most use cases."

The strong version takes the same amount of time. The difference is sequence: scope first, then hoisting, then the practical implication. That order is easy to follow and easy to probe.

Stop calling it scope trivia — this is about where code actually behaves

Scope is not vocabulary. It's a description of where a variable is accessible at runtime, and getting it wrong causes real bugs. The reason JavaScript scope interview questions trip people up is that candidates memorize definitions without picturing what actually happens when the JavaScript engine executes a block.

Block scope versus function scope without the jargon fog

A block is anything between curly braces: an `if` statement, a `for` loop, a standalone `{}`. `let` respects those boundaries. `var` does not — it escapes them and lives at the function level, or at the global level if there's no enclosing function.

The reason candidates get this wrong is they think of scope as a property of the keyword, not as a spatial thing. A `var` declared inside an `if` block is not contained by that `if`. It belongs to the function. That's the behavior that produces bugs.

The browser-console weirdness nobody mentions

There's one nuance worth having ready: at the top level of a browser script, `var` declarations become properties of the `window` object. `let` declarations do not. But in ES modules — which is what you're likely writing in any modern project — neither `var` nor `let` attaches to `window`. The ECMAScript specification makes this distinction explicit: module code runs in its own scope, separate from the global object. So "global" doesn't mean the same thing everywhere, and if an interviewer pushes on this, acknowledging the module behavior shows you're working from actual knowledge rather than a blog summary.

What this looks like in practice

This is the example that makes the concept click. `var` leaks. `let` doesn't. In a real debugging session, a leaked `var` declaration can overwrite something declared earlier in the function, and the error message won't point you to the right line. That's the practical cost of function scoping when you expected block scoping.

Hoisting is where most answers go sideways

Hoisting is the concept that derails more hoisting interview answers than any other. Candidates say the word confidently, then describe it incorrectly — usually because they learned a shortcut that isn't quite right.

Say what hoisting means before you try to sound smart

The common failure: "hoisting means the variable gets moved to the top." That's close but wrong in a way that matters. The variable declaration is processed before execution begins — the variable binding is created — but the code itself doesn't move anywhere. For `var`, the binding is created and initialized to `undefined`. For `let` and `const`, the binding is created but not initialized. That difference is the whole point.

The temporal dead zone is the part that makes let feel stricter

The temporal dead zone (TDZ) is the period between when a `let` or `const` variable's binding is created and when the line of code that declares it actually runs. During that window, the variable exists in the scope but cannot be accessed. Trying to access it throws a `ReferenceError`. This is not the same as "let is not hoisted" — it is hoisted, but it stays inaccessible until initialization. The TDZ is a deliberate design choice to catch the class of bugs that `var`'s `undefined`-on-access behavior hides.

What this looks like in practice

One real example of where this bites: a developer working on a legacy codebase assumed that since both `var` and `let` are "hoisted," they behaved the same before their declaration line. They were using `let` in a refactored section and expected the same silent `undefined` they'd been getting with `var`. Instead they got a thrown error in production — which was actually better than the silent failure, but it wasn't what they anticipated. The TDZ is stricter by design, and that strictness surfaces bugs that `var` would have swallowed. MDN's reference on the temporal dead zone documents this behavior precisely.

Show the loop bug, because that is the proof people remember

The loop closure bug is the single most convincing demonstration of why let vs var interview answers need to go beyond definitions. It's concrete, it's visual, and it shows the behavioral difference instead of just naming it.

Why var inside a loop creates the classic closure mistake

When you use `var` in a `for` loop, there is exactly one binding for that variable across all iterations. The loop counter increments, but every callback or closure created inside the loop shares a reference to that same single binding. By the time any of those callbacks execute, the loop has finished and the variable holds its final value. Every callback sees the same thing.

Let fixes the loop without magic

`let` creates a new binding for each iteration of the loop. Each callback closes over its own copy of the loop variable, frozen at the value it had during that iteration. There's no trick involved — it's a direct consequence of block scoping. Each loop body is its own block, and `let` scopes to that block.

What this looks like in practice

This exact pattern shows up in interview exercises and in real codebases. A common version: event listeners attached inside a loop, where every listener fires the same handler with the same index because `var` was used. Switching to `let` fixes it immediately, and understanding why — one binding per iteration — is the explanation that separates a candidate who knows the answer from one who just knows the fix. The MDN closures documentation covers the closure behavior underlying this example in detail.

Answer const the right way before the interviewer asks

In any const vs let interview exchange, the question about `const` is coming. Have the answer ready before it's asked, because getting it wrong after a strong `let`/`var` explanation undermines the whole thing.

Const does not mean the thing itself can never change

`const` prevents reassignment of the binding. It does not prevent mutation of the value. If you declare a `const` object, you cannot point that variable at a different object — but you can change the properties of the object it already points to. Same with arrays: you can't reassign the array, but you can push items into it.

What interviewers are really testing here

The question isn't about `const` syntax. It's about whether you understand the difference between a reference and a value. Candidates who say "const makes it immutable" are describing what they wish it did, not what it does. Interviewers who ask this are checking whether you've actually worked with objects in JavaScript or whether you're operating on a mental model borrowed from a typed language.

What this looks like in practice

The bug this causes in real code: a developer declares a config object with `const`, assumes it's locked, and then a utility function mutates one of its properties. No error is thrown. The mutation is silent. The fix — if you actually need immutability — is `Object.freeze()`, not `const`. That's worth mentioning if the interviewer pushes: "`const` gives you binding immutability. For deep immutability you'd need `Object.freeze()` or a library like Immer."

Use the follow-up traps to separate real understanding from memorized lines

The follow-up questions on let vs var interview questions are where the real evaluation happens. The first answer is almost always scripted. The follow-ups are where the interviewer finds out what's underneath.

The follow-ups that show up most often

  • "Why does let help with closures?" — Tests whether you understand the per-iteration binding, not just the syntax swap.
  • "Can you redeclare a variable with let?" — No. `var` allows redeclaration in the same scope; `let` throws a SyntaxError.
  • "Is let hoisted?" — Yes, but it stays in the TDZ. Candidates who say "no" are wrong in a way that reveals they learned a shortcut.
  • "What's the difference between const and let?" — Reassignment versus mutation. See above.
  • "What happens if you use var in a module?" — It doesn't attach to `window`, because modules have their own scope.

Each of these catches candidates who learned the comparison as a slogan rather than as a model of how the runtime behaves.

What a weak answer sounds like

"So `let` is better because it's block-scoped, and `var` is kind of old and has issues. Hoisting means the variable goes to the top of the file, and `let` doesn't do that. `const` is like `let` but you can't change it at all, so it's fully immutable. The loop thing is because `var` doesn't scope properly."

This answer mixes up three separate errors: hoisting described as physical movement, `let` described as not hoisted, and `const` described as immutable. Any one of these would prompt a follow-up. All three together signals that the candidate has read about these concepts but hasn't worked through the mechanics.

What this looks like in practice

Interviewer: "You mentioned let helps with loops — why exactly?"

Weak: "Because let is block-scoped, so it works better."

Strong: "Because `let` creates a new binding for each iteration of the loop. With `var`, there's one shared binding, so every callback closes over the same variable and sees its final value. With `let`, each iteration gets its own binding, so each callback captures the value it had at that point."

Interviewer: "What about const — can you mutate a const object?"

Strong: "Yes — `const` only prevents reassignment of the binding. The object itself can still be mutated. If you need actual immutability, you'd use `Object.freeze()` or handle it at the application level."

Two follow-ups, same core explanation, no backtracking. That's the target.

Judge the answer by whether it predicts bugs, not whether it sounds polished

The real rubric for let vs var interview questions isn't fluency. It's whether the candidate's explanation connects to behavior — whether they can use the concept to predict what code will do before running it.

A good answer talks about behavior, not vocabulary

A candidate who says "let is block-scoped" and stops there has named a property. A candidate who says "let is block-scoped, so in a for loop each iteration gets its own binding, which means closures inside the loop capture the right value" has demonstrated a model. The model is what matters. Vocabulary is just the shorthand for it.

The red flags are easy to spot

  • Mixing up block scope and function scope mid-explanation ("so `let` is scoped to the function, or the block, kind of both")
  • Claiming `let` is not hoisted — it is, just not initialized
  • Saying `const` makes objects immutable — it prevents reassignment, not mutation
  • Using "hoisting" without explaining what's actually accessible before declaration

Any one of these tells a senior interviewer that the candidate is pattern-matching on keywords rather than reasoning from a model.

What this looks like in practice

Two quick tests that reveal real understanding in under two minutes:

  • The loop test: "What does this print?" followed by the `setTimeout`/`var` example. A candidate who knows why it prints `3, 3, 3` — not just that it does — understands closures and binding.
  • The const-object test: "Can I change a property on a `const` object?" A candidate who says yes and explains why understands references versus values.

These aren't trick questions. They're behavioral checks. A strong candidate doesn't just answer them correctly — they explain the mechanism, which is the evidence that the understanding is real rather than rehearsed.

How Verve AI Can Help You Prepare for Your Interview With let vs var

The gap between knowing these concepts and being able to explain them under live pressure is a performance gap, not a knowledge gap. What closes it is repetition against real follow-up questions — not rereading the theory one more time. That's the specific problem Verve AI Interview Copilot is built for: it listens in real-time to your spoken answer and responds to what you actually said, not a canned prompt. If you give the weak version of the hoisting answer, Verve AI Interview Copilot surfaces the follow-up immediately — "you said let isn't hoisted; can you clarify what you mean?" — which is exactly the pressure that reveals whether your answer will hold. The practice sequences that matter most are the ones where the tool responds to your specific gaps, not generic preparation scripts. Verve AI Interview Copilot does that while staying invisible during the session, so the experience mirrors a real interview rather than a study session.

FAQ

Q: What is the simplest interview-ready difference between let and var?

`let` is block-scoped; `var` is function-scoped. `var` is hoisted and initialized to `undefined`, so accessing it before its declaration is silent. `let` is hoisted but stays in the temporal dead zone until initialization, so accessing it early throws a ReferenceError. In practice, `let` is safer because it behaves closer to what you'd expect.

Q: Why does var create bugs in loops and closures while let usually does not?

`var` creates a single binding for the entire loop. Every callback or closure inside the loop shares that same binding, so by the time they execute, the variable holds its final value. `let` creates a new binding per iteration, so each closure captures the value from that specific iteration.

Q: How do scope, hoisting, and the temporal dead zone differ for let versus var?

Scope: `var` is function-scoped, `let` is block-scoped. Hoisting: both are hoisted, but `var` is initialized to `undefined` while `let` is left uninitialized. The temporal dead zone is the window between when `let`'s binding is created and when the declaration line executes — accessing the variable in that window throws a ReferenceError.

Q: Is const the same as immutability, and how do you explain that clearly in an interview?

No. `const` prevents reassignment of the binding, not mutation of the value. A `const` object can have its properties changed; a `const` array can have items pushed into it. True immutability requires `Object.freeze()` or an equivalent. The distinction is between the binding (what the variable points to) and the value (the contents of what it points to).

Q: What is the best 30-second answer if an interviewer asks why let replaced var?

"`let` replaced `var` as the default because it's block-scoped, which means it stays contained to the block where it's declared. `var` leaks to the function scope, which causes unexpected behavior in loops and conditionals. `let` also enforces the temporal dead zone, which catches use-before-declaration bugs that `var` would silently swallow as `undefined`."

Q: What common wrong answers do candidates give about hoisting and redeclaration?

The most common errors: saying `let` is not hoisted (it is, just not initialized), describing hoisting as the code physically moving (it's about when bindings are created), and claiming `var` can be redeclared freely everywhere (it can in the same scope, but not across scopes the same way). On redeclaration: `var` allows it in the same scope without error; `let` throws a SyntaxError.

Q: How should you judge whether a candidate really understands the practical difference?

Give them the `setTimeout`-in-a-loop example and ask what it prints. Then ask whether you can mutate a `const` object. A candidate who answers both correctly and explains the mechanism — not just the outcome — has a working model of JavaScript scoping. A candidate who gets the right answer but can't explain why is pattern-matching, not reasoning.

---

You came into this article knowing what `let` and `var` are. The gap was never the knowledge — it was having a structure you could actually speak under pressure. You now have a 30-second script, the loop example that makes the concept concrete, and the follow-up traps that catch candidates who memorized instead of understood. One thing left: say the 30-second answer out loud. Not to yourself silently — out loud, once. That's the practice that makes the difference between an answer that sounds rehearsed and one that sounds like you know it.

JM

James Miller

Career Coach

Ace your live interviews with AI support!

Get Started For Free

Available on Mac, Windows and iPhone