JavaScript interviews test more than syntax recall. Interviewers want to see that you understand why the language behaves the way it does — and that you can reason through edge cases on the spot.
Here are 10 questions that come up consistently, from junior to mid-level roles, along with focused sample answers you can adapt.
1. What is a closure and when would you use one?
Sample answer: A closure is a function that retains access to variables from its outer scope even after that outer function has returned. JavaScript creates closures automatically whenever a function is defined inside another function.
count persists between calls because the inner function closes over it. Closures are useful for data encapsulation (hiding state from the outside world), factory functions, and memoization. A common interview gotcha: closures in loops. Use let (block-scoped) instead of var to avoid all loop iterations sharing the same variable reference.
2. What is hoisting and how does it differ between var, let, and const?
Sample answer: Hoisting is JavaScript's behavior of moving declarations to the top of their scope during the compilation phase — before any code runs.
| Declaration | Hoisted? | Initialized? | Accessible before declaration? |
|---|---|---|---|
| var | Yes | As undefined | Yes (returns undefined) |
| let | Yes | No | No (Temporal Dead Zone) |
| const | Yes | No | No (Temporal Dead Zone) |
| Function declaration | Yes | Fully | Yes |
The practical takeaway: var is silently initialized as undefined, which hides bugs. let and const throw a ReferenceError if you try to use them before their declaration — which is actually safer behavior. Prefer const by default, let when reassignment is needed, and avoid var in new code.
3. Explain the JavaScript event loop.
Sample answer: JavaScript is single-threaded — it can only do one thing at a time. The event loop is the mechanism that lets it handle asynchronous work without blocking.
Here's the execution order:
- Call stack — synchronous code runs here first.
- Microtask queue — Promise callbacks (.then, .catch, async/await) drain completely after each task.
- Macrotask queue — setTimeout, setInterval, and I/O callbacks run one at a time, after the microtask queue is empty.
setTimeout fires after the Promise .then even with a 0ms delay — because Promises are microtasks and drain before macrotasks. This distinction trips up a lot of candidates.
4. What is the prototype chain?
Sample answer: Every JavaScript object has an internal link to another object called its prototype. When you access a property that doesn't exist on an object, JS walks up the prototype chain until it either finds the property or reaches null.
dog doesn't have a speak property directly — JS finds it on Animal.prototype. ES6 class syntax is syntactic sugar over this same prototype system. Interviewers often ask you to explain the difference between proto, prototype, and Object.getPrototypeOf() — know that prototype is on constructor functions, proto is the actual link between instances.
5. How do Promises work, and when would you use async/await instead?
Sample answer: A Promise represents a value that will be available in the future — it's either pending, fulfilled, or rejected. Promises replaced callback hell with a chainable API.
async/await is syntactic sugar over Promises that makes async code read like synchronous code:
Use async/await when readability matters or when you need sequential async steps. Use Promise combinators (Promise.all, Promise.allSettled) when you want to run multiple async operations in parallel.
6. What does this refer to, and how do arrow functions change it?
Sample answer: this in JavaScript refers to the execution context — who called the function. The value depends on how the function is invoked:
- Method call (obj.method()) → this is obj
- Regular function call → this is undefined (strict mode) or the global object
- Constructor call (new Fn()) → this is the new instance
- Explicit binding (.call, .apply, .bind) → this is whatever you pass
Arrow functions don't have their own this. They capture this from the surrounding lexical scope at the time they're defined. This makes them useful inside class methods or callbacks where you'd otherwise lose the correct this:
7. What are the key ES6+ features you use regularly?
Interviewers don't want a list — they want to see you explain tradeoffs.
Destructuring — pull values from arrays or objects concisely. Particularly useful in function parameters to name what you need.
Spread / Rest — ... spreads an iterable into individual elements, or collects remaining elements. Common in state updates and function signatures.
Arrow functions — shorter syntax and lexical this. Not a replacement for all functions (avoid them as object methods where you need dynamic this).
Template literals — backtick strings with ${} interpolation. Cleaner than string concatenation.
Modules (import/export) — named and default exports let you split code into reusable files. Interviewers sometimes ask about the difference between CommonJS require and ES modules.
Optional chaining (?.) and nullish coalescing (??) — added in ES2020, now ubiquitous. user?.address?.city avoids throwing if address is undefined; config.timeout ?? 3000 defaults to 3000 only when the left side is null or undefined.
8. How would you explain the difference between == and ===?
Sample answer: === (strict equality) checks value and type — no coercion. == (loose equality) coerces types first, which produces surprising results:
The practical rule: always use === unless you specifically need the null == undefined comparison (which is one of the few legitimate uses of ==). Loose equality makes code harder to reason about and is a frequent source of bugs.
9. What is debounce and how would you implement it?
Debounce is a technique that delays calling a function until a specified time has passed since the last invocation — useful for search inputs, resize handlers, and anywhere you want to limit expensive operations.
Interviewers often follow up by asking about throttle (runs at most once per interval, regardless of how many times it's called) — know the difference. Debounce waits for the user to stop; throttle fires on a regular schedule.
10. How do you handle errors in async JavaScript?
Sample answer: Error handling strategy depends on whether you're using Promise chains or async/await.
With .catch() on a chain:
With try/catch in async functions:
A common mistake: forgetting that an unawaited Promise won't be caught by a surrounding try/catch. If you forget await, the error propagates as an unhandled rejection. Use Promise.allSettled when you want results from multiple Promises regardless of individual failures — unlike Promise.all, it doesn't short-circuit on the first rejection.
Passing the Technical Screen
Strong answers to these questions get you through the coding screen. But the conversation before and after the technical round matters too. If you're preparing for JS interviews, Articuler can find the actual hiring manager for the role and help you prep for the interview on that specific person — their background, what they care about, and how to open the conversation. That 15-minute conversation with the right person often determines whether your technical answers land.
If you want to pair technical prep with a better approach to reaching out, check the tell me about yourself sample answers guide — it covers how to position yourself compellingly in the first 60 seconds of any interview.
FAQ
What JavaScript topics come up most in junior interviews?
Closures, hoisting, the event loop, and this binding are the most common. You'll also likely get at least one question on Promises or async/await, and a small coding exercise (often debounce, array methods, or a simple DOM task).
Do I need to know ES6+ features for a JavaScript interview?
Yes. Interviewers expect you to know destructuring, arrow functions, template literals, spread/rest, and modules. Optional chaining (?.) and nullish coalescing (??) come up frequently at mid-level.
How should I handle a JavaScript question I don't know?
Walk through your reasoning out loud. Say what you do know (related concepts, what the expected behavior might be) and acknowledge the gap directly. Most interviewers value reasoning process over memorized answers.