JavaScript interview questions & practice path
Closures, the event loop, prototypes, and async patterns. Learn what interviewers probe, drill the questions until answers come fast, then prove it in a scored mock, all in one JavaScript path inside Round Zero.
- Concept lessons that explain the why, not just the answer
- Practice questions with adaptive follow-ups and flashcards
- A scored mock with evidence quoted from your own answers
Sample JavaScript questions
What a strong answer covers, and the mistakes interviewers watch for. The scored path drills every one with live follow-ups.
What is the difference between var, let, and const, and what is the temporal dead zone?
easyA strong answer covers
- var is function-scoped and hoisted with an initial value of undefined; let and const are block-scoped ({ } bounded).
- let and const are hoisted too but not initialized, so accessing them before their declaration throws a ReferenceError. That gap is the temporal dead zone.
- const forbids reassignment of the binding, but the value can still be mutated (a const object's properties can change); it is not deep immutability.
- Practical guidance: default to const, use let when reassignment is needed, avoid var in new code.
Common mistakes
- Claiming let and const are not hoisted at all, rather than hoisted-but-uninitialized.
- Saying const makes an object immutable instead of just preventing rebinding.
- Confusing block scope with function scope, e.g. expecting a var inside an if to be block-local.
Explain closures. Give a concrete example where one is useful, and describe the classic loop bug.
mediumA strong answer covers
- A closure is a function bundled with references to the lexical scope in which it was defined, so it retains access to those variables even after the outer function returns.
- Useful cases: data privacy / module pattern (a counter with a private count), partial application / currying, and memoization caches.
- Classic bug: a for loop with var capturing the same shared binding, so all callbacks log the final value. Fixing it with let gives each iteration its own binding.
- Notes that closures keep referenced variables alive in memory, which can cause leaks if long-lived closures capture large objects.
Common mistakes
- Describing a closure as just a nested function, missing that it captures and retains its enclosing scope.
- Not being able to explain why var breaks the loop while let fixes it (shared vs per-iteration binding).
- Overlooking the memory implication that captured variables cannot be garbage collected while the closure lives.
How is the value of `this` determined in JavaScript, and how do arrow functions differ?
mediumA strong answer covers
- For regular functions `this` is set by the call site: method call binds to the object before the dot, plain call is undefined in strict mode (or the global object otherwise), new binds to the fresh instance.
- call, apply, and bind explicitly set `this`; bind returns a permanently bound copy.
- Arrow functions have no own `this`; they capture `this` lexically from the enclosing scope, which is why they are ideal for callbacks inside methods.
- A strong answer names the precedence order: new > explicit bind/call/apply > implicit method call > default.
Common mistakes
- Saying `this` is determined by where a function is defined rather than how it is called (true only for arrow functions).
- Using an arrow function as an object method and expecting `this` to point at the object.
- Forgetting that a detached method (const f = obj.method) loses its implicit binding when called alone.
Predict the output order of a script mixing synchronous code, setTimeout, and a resolved Promise. Explain why.
hardA strong answer covers
- JavaScript is single-threaded with a call stack; the event loop runs queued work only when the stack is empty.
- Synchronous code runs first. Then the microtask queue (Promise .then/.catch, queueMicrotask, await continuations) is fully drained before any macrotask.
- setTimeout/setInterval callbacks are macrotasks and run after all pending microtasks, so a resolved Promise's .then fires before a setTimeout(0).
- The loop drains all microtasks after each macrotask, so a correct trace is: sync -> microtasks -> one macrotask -> its microtasks -> next macrotask.
Common mistakes
- Treating setTimeout(fn, 0) as immediate and ordering it before Promise callbacks.
- Not distinguishing the microtask queue from the macrotask queue at all.
- Forgetting that await pauses the async function and schedules the rest as a microtask, changing ordering.
How do you run several async operations in parallel and handle partial failure? Contrast Promise.all with Promise.allSettled.
hardA strong answer covers
- Kick off the promises before awaiting so they run concurrently, then await the combinator, rather than awaiting each in sequence.
- Promise.all resolves with an array of results once all succeed, but rejects immediately on the first rejection (fail-fast), discarding the other results.
- Promise.allSettled always resolves with a status/value-or-reason object per promise, so you can inspect partial success; use it when one failure should not sink the batch.
- Mentions Promise.race and Promise.any, and that async/await is syntactic sugar over promises so try/catch wraps awaited rejections.
Common mistakes
- Awaiting promises one at a time in a loop and calling it parallel, when it is actually sequential.
- Reaching for Promise.all when partial failure must be tolerated (allSettled is the right tool).
- Forgetting that a rejected promise without a catch produces an unhandled rejection.
Explain prototypal inheritance and the prototype chain. How does it relate to ES6 class syntax?
mediumA strong answer covers
- Every object has an internal link to a prototype object; property lookups walk this chain until found or until it reaches null.
- A function's prototype property becomes the [[Prototype]] of instances created with new, so shared methods live once on the prototype rather than per instance.
- ES6 class is syntactic sugar over this: methods go on Class.prototype, extends sets up the chain, and super calls the parent constructor.
- Distinguishes own properties from inherited ones (hasOwnProperty) and knows Object.create makes a new object with a chosen prototype.
Common mistakes
- Believing JavaScript classes introduce classical inheritance rather than wrapping prototypes.
- Confusing the instance-facing __proto__ / [[Prototype]] with the function's prototype property.
- Assuming inherited properties show up as own properties, breaking for...in or hasOwnProperty reasoning.
How JavaScript answers are scored
Mental model of the runtime
40%Explains how JavaScript actually executes: the single-threaded event loop, call stack, closures over lexical scope, prototype chain, and how async work is scheduled rather than blocking.
Correctness on edge cases
35%Gets the tricky details right: hoisting and the temporal dead zone, dynamic `this` binding, coercion rules, microtask vs macrotask ordering, and reference vs value semantics.
Communication and reasoning
25%Traces execution step by step, predicts output before running it, states assumptions, and reaches for the idiomatic modern tool (const/let, async/await, array methods) with a reason.
Role tracks that include JavaScript
Related Programming Languages skills
All skills →No spam. Unsubscribe anytime.
Ready to master JavaScript?
Sign up free. Your JavaScript path includes lessons, drills, flashcards, and a scored mock with feedback on what to fix.
- ✓ Concept lessons plus practice questions
- ✓ Flashcards for spaced repetition
- ✓ A scored mock with evidence quotes
Questions & answers
- What JavaScript interview questions should I practice?
- Start with the core areas JavaScript interviewers probe: What is the difference between var, let, and const, and what is the temporal dead zone; Explain closures. Give a concrete example where one is useful, and describe the classic loop bug.; How is the value of `this` determined in JavaScript, and how do arrow functions differ. This page outlines strong answers and common mistakes, and the scored path drills each one with follow-ups.
- Is the JavaScript practice free?
- Yes, you can start a JavaScript path free inside Round Zero. It generates lessons, practice questions, flashcards, and a scored mock. Sign up to unlock the full drills and your evidence-backed scorecard.
- How is this different from a JavaScript question list?
- A static list gives you questions with no feedback. Round Zero runs a live scored practice that probes your actual answers, rotates difficulty, and tells you exactly what to fix, grounded in a JavaScript rubric.
- How should I prepare for a JavaScript interview?
- Learn the concepts, drill the questions until answers come fast, then prove it in a scored mock. Round Zero sequences all three so you know you are ready, not just that you read about JavaScript.
- How is a JavaScript answer scored?
- JavaScript answers are scored on mental model of the runtime, correctness on edge cases, communication and reasoning, with evidence quoted from what you actually said, so feedback is specific instead of generic praise.