Skip to main content
Back to blog// interview prep

The JavaScript Intermediate Interview

Mid-level JavaScript interviews stop asking for definitions and start asking you to predict microtask order and implement debounce, bind, and memoize from scratch. Here's the real question set, attempt, then reveal.

NK

Nicanor Korir

Author

July 15, 2026
18 min read
JavaScriptInterviewIntermediateClosuresEvent LoopAsyncWeb Development

The jump from junior to mid-level interviews is where a lot of good engineers stumble, not because they lack the knowledge, but because the format changes and they prepare for the wrong thing.

At the junior level, interviewers ask "what does this print?" At the mid level, they ask two harder questions: "predict the exact order this async code runs in," and "now implement the utility you've been importing." You don't get to import { debounce } from 'lodash', you write it, live, and handle this and the edge cases while you talk.

I run these interviews now, and the pattern is consistent: candidates who've used closures and async/await for years but never had to reconstruct them freeze up. This article is built to fix that. Every question below is interactive, read it, solve it on paper or in your head first, then reveal the full answer. For the "implement X" ones, genuinely try to write the code before you peek. That's the muscle the interview tests.

Want to drill these against a timer instead of reading top to bottom? The interactive practice hub turns the whole series into flashcards with progress tracking.

What the mid-level round is really testing

A mid-level interview (usually 45-60 minutes in a shared editor) screens for depth and the ability to build, not just use:

  • Deep, applied understanding of closures, this, and prototypes, not the one-line definition.
  • Predicting microtask vs macrotask ordering in mixed async code.
  • Implementing everyday utilities from first principles, debounce, bind, memoize, a small event emitter.
  • Trade-off awareness, naming when a pattern helps and when it hurts, before you're asked.

The strongest signal you can send: reason about the call stack, the microtask queue, and the macrotask queue explicitly, and name the trade-off in your own solution before the interviewer probes for it.

Closures, beyond "a function inside a function"

Every mid-level interview probes closures, and the shallow answer gets caught immediately. Expect the classic loop bug, and expect a follow-up about why the variables stay alive.

Q1
Closures★★Live coding

What does this log? Then fix it to print 0, 1, 2, first with a one-word change, then without let.

JavaScript
javascript
1
2
3
  • #closures
  • #var
  • #let
  • #event-loop
Q2
Closures★★Technical screen

Beyond 'a function that remembers its scope', what actually keeps a closure's variables alive, and when does that become a memory problem?

  • #closures
  • #encapsulation
  • #memory

The event loop & async ordering

This is the mid-level topic. If you take one thing from this article, make it the microtask-vs-macrotask rule, it's asked in some form in the majority of interviews.

Q3
Event loop★★Live coding

Predict the exact output order. This is the classic microtask-vs-macrotask question.

JavaScript
javascript
1
2
3
4
  • #event-loop
  • #microtask
  • #promises
  • #settimeout
Q4
Async★★Live coding

What does async/await actually desugar to? And what does this print?

JavaScript
javascript
1
2
3
4
5
6
7
8
  • #async-await
  • #promises
  • #microtask
Q5
Async★★Technical screen

Compare Promise.all, Promise.allSettled, Promise.race, and Promise.any. When would you pick each?

  • #promise-all
  • #allSettled
  • #race
  • #any

Implement it yourself: debounce, throttle & memoize

Here's where the interview gets hands-on. These three come up constantly because they test closures, this, and setTimeout all at once, and reveal whether you actually understand the tools you use daily.

Q6
Higher-order functions★★Live coding

Implement debounce(fn, delay). It should postpone calling fn until delay ms have passed since the last call, and preserve this and arguments.

  • #debounce
  • #closures
  • #this
Q7
Higher-order functions★★Live coding

Implement throttle(fn, interval) and explain how it differs from debounce.

  • #throttle
  • #performance
  • #closures
Q8
Higher-order functions★★Live coding

Implement a memoize(fn) that caches results by arguments. What are its real-world limitations?

  • #memoization
  • #caching
  • #closures

this, call/apply/bind & prototypes

The this keyword and the prototype chain are the parts of JavaScript that feel like folklore until they click. Mid-level interviews check that they've clicked, often by having you implement bind yourself.

Q9
this★★Live coding

What does each log print?

JavaScript
javascript
1
2
3
4
5
6
7
8
9
  • #this
  • #call
  • #apply
  • #bind
Q10
this★★★Live coding

Implement Function.prototype.myBind, your own version of bind. It must fix this, support partial application, and behave reasonably when the bound function is called with new.

  • #bind
  • #this
  • #prototypes
Q11
Prototypes★★Technical screen

Explain prototypal inheritance and the prototype chain. What happens when you read obj.toString()?

  • #prototypes
  • #inheritance
  • #this

Objects, copying & data structures

Once you're comfortable with references (the junior topic), the mid-level version asks about deep vs shallow copying and the modern tools for each.

Q12
Objects★★Technical screen

What's the difference between a shallow and a deep copy? Compare the ways to make each in modern JS.

  • #deep-copy
  • #shallow-copy
  • #structuredClone

Functional patterns & language features

Rounding out the round: currying, generators, the observer pattern, and module systems. These separate candidates who know ES6 syntax from those who understand why the features exist.

Q13
Functional★★★Live coding

Implement curry(fn) so that curry(add)(1)(2)(3) and curry(add)(1, 2)(3) both work for a 3-arg add.

  • #currying
  • #closures
  • #partial-application
Q14
Patterns★★Live coding

Implement a small event emitter with on, off, and emit. This is the observer pattern.

  • #event-emitter
  • #observer
  • #pub-sub
Q15
Iterators★★★Technical screen

What are generators, and what's a real use case? Write a generator for an infinite id sequence.

  • #generators
  • #iterators
  • #lazy
Q16
Modules★★Technical screen

Compare ES Modules and CommonJS. Why does the difference matter for tooling like tree-shaking?

  • #esm
  • #commonjs
  • #bundling

How to prepare for the mid-level round

The knowledge is mostly there by now, the gap is usually fluency under a live editor. What works:

  • Implement the utilities from memory. Close the tab and write debounce, throttle, bind, curry, and a small event emitter cold. If you can't, you don't know them yet, recognising the code isn't the same as producing it.
  • Trace async snippets by hand. Draw the call stack, the microtask queue, and the macrotask queue as three columns, and step through. Do it until "microtasks drain before the next macrotask" is reflex.
  • Practise narrating trade-offs. After you solve something, say the sentence: "the trade-off here is..." Interviewers score judgment as much as correctness.

Green flags

  • You reason about the call stack, microtask, and macrotask queues by name.
  • Your debounce/bind correctly handles `this`, arguments, and edge cases.
  • You name the trade-off before the interviewer asks.

Red flags

  • Knowing async/await syntax but not what it desugars to.
  • A closure explanation that stops at "a function inside a function."
  • Implementations that ignore `this`/arguments or leak state.

Where to go next

If these feel comfortable, the advanced / principal guide is where it gets genuinely hard, frontend system design, performance at scale, memory leaks, race conditions, and the judgment questions that decide senior offers. If any of the closures or async here felt shaky, drop back to the beginner guide to shore up the foundations first.

To drill everything as timed flashcards, head to the interview practice hub.

Stay in the Loop

Get occasional updates on AI engineering, robotics projects, and lessons from building startups. No spam, unsubscribe anytime.