Boarding pass · JavaScript Intermediate
JavaScript · Intermediate interview
An AI mock interview for developers comfortable with JavaScript basics. Go deeper into closures, prototypes and this binding, the event loop, and modern language features.
- Voice interview
- Live feedback
- Browser-only
- No installation required
Your report · sample
AI Readiness Score
Finish the mock and get this report — scored on content and English, with concrete tips and a model answer for every question, plus a study plan.
Your flight path
Five steps to interview-ready.
From a quick warm-up to a personalised study plan — here's the whole loop, and what you get at each gate.
Step 01
Preparation
Skim the topics and warm up — you're briefed before takeoff.
Step 02
AI Interview
A realistic AI interviewer asks tailored questions — answer by voice or text.
Step 03
Instant Score
Finish and get a 0–100 readiness score across content and English.
Step 04
AI Feedback
Concrete tips and a rewritten model answer for every response.
Step 05
Study Plan
A personalised plan targets your weakest areas — so the next run scores higher.
Preview the AI demo
See one answer scored, end to end.
The whole loop on sample data — question, your answer, instant feedback and a study plan. Hover to pause.
Interviewer · Question 1
“Tell me about yourself.”
Who it's for
- Developers writing JavaScript daily
- Engineers who want to understand the 'why'
- Anyone targeting mid-level frontend roles
- Devs sharpening before interviews
What you'll practice
- Closures and the module pattern
- Prototypes and this binding
- The event loop and promise combinators
- Destructuring, modules and copying
Topics covered
What this level expects.
Closures & scope
- Closures
- Data privacy
- Module pattern
Prototypes & this
- Prototype chain
- this binding
- call/apply/bind
Async & event loop
- Event loop
- Promise combinators
- Error handling
Language features
- Destructuring & spread
- ES modules
- Copying
Practice questions
12 questions, with model answers.
Read them, then run the live mock to answer out loud and get scored. Tap any question to reveal a model answer.
01What is a closure and what is it used for?Closures & scope
A closure is a function bundled with references to the variables from the scope where it was created, so it can still access them after that scope has returned. It's the basis for data privacy (variables only the returned function can touch), function factories, memoization, and maintaining state in callbacks. Essentially, inner functions remember their birthplace.
function counter() { let n = 0; return () => ++n; }
const next = counter(); next(); // 102How do closures give you data privacy?Closures & scope
Because variables in an outer function's scope aren't accessible from outside, only the inner functions that close over them can read or modify them. You expose just the functions you want as a public API and keep the state private — the pre-class way of making 'private' fields, and still common in modules and hooks.
03Why does a var loop with setTimeout log the same number, but let works?Closures & scope
With var, the loop variable is function-scoped — there's one shared binding, so by the time the deferred callbacks run, they all see the final value. With let, each iteration creates a new block-scoped binding, so each closure captures its own value. It's a classic demonstration of closures capturing variables (bindings), not values.
for (let i = 0; i < 3; i++) setTimeout(() => console.log(i)); // 0,1,2
04How does prototypal inheritance work in JavaScript?Prototypes & this
Every object has an internal link to a prototype object, and when you access a property that isn't on the object itself, JS walks up this prototype chain until it finds it or reaches null. Constructors and classes set up these prototype links so instances share methods without copying them. It's delegation rather than the classical copy-based inheritance of other languages.
05What determines the value of this?Prototypes & this
this is set by how a function is called, not where it's defined. The rules in priority: new binding (this is the new object), explicit binding (call/apply/bind), implicit binding (the object before the dot), and default (undefined in strict mode, else the global object). Arrow functions ignore all this and inherit this from their lexical scope.
06What do call, apply, and bind do?Prototypes & this
All three set this for a function. call invokes it immediately with this and arguments listed individually; apply is the same but takes arguments as an array; bind returns a new function with this (and optionally some arguments) permanently fixed, to call later. You use them to borrow methods or control this in callbacks.
greet.call(user, "hi"); greet.apply(user, ["hi"]); const bound = greet.bind(user);
07How does the event loop order microtasks and macrotasks?Async & event loop
The call stack runs synchronous code first. Then, after each macrotask (a timer, I/O, or event callback) and whenever the stack empties, the engine drains the entire microtask queue (promise callbacks, queueMicrotask) before the next macrotask. That's why a resolved promise's .then runs before a setTimeout(…, 0) scheduled at the same time.
console.log(1); setTimeout(() => console.log(4)); Promise.resolve().then(() => console.log(3)); console.log(2); // 1,2,3,4
08What's the difference between Promise.all, race, allSettled, and any?Async & event loop
Promise.all resolves when all succeed (and rejects fast if any fails). Promise.allSettled waits for all and reports each outcome, never short-circuiting. Promise.race settles as soon as the first one settles, success or failure. Promise.any resolves with the first success and only rejects if all fail. You pick based on whether you need everything, the fastest, or fault tolerance.
09How do you handle errors in asynchronous code?Async & event loop
With promises, attach .catch (or pass a rejection handler); with async/await, wrap awaits in try/catch. Unhandled rejections should be monitored (window 'unhandledrejection' / process event) but the real fix is handling them at the right level. A common bug is forgetting to await or return a promise, so its rejection escapes the try/catch.
10How do destructuring, spread, and rest work?Language features
Destructuring pulls values out of arrays/objects into variables, with defaults and renaming. Spread (...) expands an iterable or object's entries into a new array/object or argument list — handy for shallow copies and merging. Rest (...) collects the remaining items into an array or object. Spread and rest share syntax but do opposite things depending on position.
const { a, ...rest } = obj;
const merged = { ...defaults, ...overrides };11What's the difference between ES modules and CommonJS?Language features
ES modules (import/export) are the language standard: statically analyzable, support tree-shaking and top-level await, and load asynchronously. CommonJS (require/module.exports) is Node's older synchronous system. The practical differences are syntax, that ESM bindings are live and static while CommonJS exports a value object, and that mixing them needs care.
12What's the difference between a shallow and deep copy, and how do you deep-copy?Language features
A shallow copy (spread, Object.assign) duplicates the top level but shares nested references, so mutating a nested object affects both. A deep copy duplicates everything recursively. The modern built-in is structuredClone, which handles many types; the old JSON.parse(JSON.stringify(x)) trick works only for plain JSON-safe data and drops functions/Dates.
Preparation tips
Walk in ready.
- Be able to write a counter using a closure
- Know the four this-binding rules
- Predict the output of mixed setTimeout/Promise code
- Know why structuredClone exists
Ready for the real thing?
Run a 6-question JavaScript mock interview, answer out loud, and get a readiness score with tips and model answers.
More intermediate interviews