JavaScript Interview Questions
43 JavaScript interview questions with worked answers, complexity notes, and runnable code you can edit in the browser — ordered easy to hard so you build up steadily. Free, no signup. Open any question for the full answer.
The runtime, not the syntax
Anyone can recite that JavaScript is single-threaded; the interview finds out whether you know what that buys you and what it costs. The event loop is the center of gravity — the call stack runs to completion, then the microtask queue (promises) drains fully, then one macrotask (a timer, an event) runs, and the cycle repeats. Half the “what logs first?” puzzles are just this ordering, and once you can trace it by hand they stop being tricks.
Closures are the other load-bearing concept. A function keeps a live reference to the scope it was defined in, which is how you get private state, memoization, and every “implement once” variant. The classic senior filter — build debounce, throttle, deepClone, or Promise.all from scratch — is really a closure-and-async test wearing a utility’s clothing: it checks that you can hold state across calls, handle the edge cases (leading vs trailing, empty input, rejection), and reason about timing.
Then there is this, which is decided by how a function is called, not where it is written — the source of most confusion and most bugs, and the reason arrow functions (which capture this lexically) exist. Prototypes explain inheritance and why class is sugar over the same chain. Coercion explains the surprising equality results. The questions here work up from these fundamentals into the from-scratch implementations, because that is exactly the arc a strong JavaScript interview follows.
Easy
- What is a closure? Scope & Closures
Explain closures. Then explain the classic var-in-a-loop bug and how to fix it. - How does this work? this binding
Explain the rules that determine `this`. Why do arrow functions behave differently? - var vs let/const, hoisting, and the TDZ Scope & Hoisting
Explain hoisting. What is the difference between var, let, and const, and what is the temporal dead zone? - == vs === and type coercion Coercion & Equality
What is the difference between == and ===? When does coercion produce surprising results?
Medium
- Event loop: micro vs macro tasks Event Loop / Async
What does this log and why? console.log(1); setTimeout(cb2); Promise.resolve().then(cb3); console.log(4); - Implement debounce Implement from scratch
Write debounce(fn, delay): return a function that delays calling fn until `delay` ms have passed since the LAST call. - Implement throttle Implement from scratch
Write throttle(fn, limit): fn runs at most once per `limit` ms, no matter how often it's called. - Prototypal inheritance & the chain Prototypes
Explain the prototype chain. What happens on property lookup? How does `class` relate to it? - Deep clone an object Implement from scratch
Implement a deep clone. Handle nested objects/arrays and circular references. - Implement curry Implement from scratch
Write curry(fn) so that sum(1)(2)(3), sum(1,2)(3) and sum(1,2,3) all work for a 3-arg fn. - Implement Function.prototype.bind Implement from scratch
Implement your own bind, and explain how it relates to call and apply. - Implement an EventEmitter (pub/sub) Implement from scratch
Build a small event emitter supporting on, off, emit, and once. - Generators and iterators Iteration Protocols
What are the iterable and iterator protocols? How do generators implement them, and what problems do they solve? - Symbols and well-known symbols Symbols
What are Symbols, why are they useful, and what are well-known symbols? - WeakMap, WeakSet, and avoiding memory leaks Memory Management
How do WeakMap and WeakSet differ from Map and Set, and how do they help prevent memory leaks? - Tagged template literals Templates & Metaprogramming
What is a tagged template literal, and what are its practical uses? - ES Modules vs CommonJS Modules
What is the difference between ES Modules and CommonJS, and why does it matter? - async/await — desugaring, sequential vs parallel, error handling Async / await
How does async/await actually work under the hood, and how do you avoid accidentally serialising independent awaits? - Optional chaining ?. , nullish coalescing ?? , and logical assignment Safe Access & Defaults
Explain ?. and ?? , how ?? differs from || , and what ??= / ||= / &&= do. - Destructuring, defaults, and rest/spread in depth Destructuring
Show non-trivial destructuring: renaming, nested, defaults, rest, and swapping — and where defaults actually fire. - Promise.all vs allSettled vs race vs any Promise Combinators
Compare the four Promise combinators. When do you reach for each, and how does failure behave? - Dynamic import() and top-level await Modules / Async Loading
Contrast static import with dynamic import(), and explain top-level await and its trade-offs. - Private class fields and methods (#) Class Encapsulation
How do #private class fields work, and how do they differ from closures, WeakMap privacy, or a leading-underscore convention? - Immutable array copies (toSorted/toReversed/with) & structuredClone Immutable Operations
Which array methods mutate vs return a copy, and how do the newer change-by-copy methods plus structuredClone help state management? - Polyfill Array map / filter / reduce Polyfills
Reimplement Array.prototype.map, filter, and reduce from scratch. What edge cases must a faithful polyfill handle? - Polyfill Function.prototype.call & apply Polyfills / this binding
Implement call and apply from scratch. How do you invoke a function with an explicit `this` without using call/apply/bind? - Deep get by path string (lodash.get) Safe Access
Implement get(obj, path, defaultValue) that safely reads a nested value via a 'a.b[0].c' path, returning the default if any link is missing. - once() — invoke a function at most once Higher-Order Functions
Write once(fn) that returns a wrapper calling fn only the first time; subsequent calls return the first result without re-invoking. - Cancellable interval / self-correcting timer Timers & Cancellation
Build a cancellable repeating timer. Why can setInterval drift, and how do you build a self-correcting one with setTimeout? - Promise-based sleep and a timeout wrapper Promises / Timers
Implement sleep(ms) as a promise, then a withTimeout(promise, ms) that rejects if the work doesn't settle in time. - Singleton — one instance, shared everywhere Creational Patterns
Implement the Singleton pattern in JavaScript. When is it justified, and why do many consider it an anti-pattern? - Factory & Abstract Factory Creational Patterns
Explain the Factory and Abstract Factory patterns. How do they decouple creation from use, and when do you reach for each? - Builder — construct complex objects step by step Creational Patterns
Implement the Builder pattern with a fluent API. What problem does it solve that a constructor doesn't? - Module & Revealing Module pattern Structural Patterns
Explain the Module and Revealing Module patterns. How do closures create private state, and how do ES modules relate? - Decorator — extend behavior by wrapping Structural Patterns
Implement the Decorator pattern. How does wrapping add behavior without modifying the original, and how does it relate to HOCs? - Facade — a simple interface over a complex subsystem Structural Patterns
Explain the Facade pattern. How does it tame subsystem complexity, and where does it appear in frontend code? - Strategy — interchangeable algorithms Behavioral Patterns
Implement the Strategy pattern. How does it replace conditional logic with pluggable, swappable behavior? - Command — actions as objects (undo/redo) Behavioral Patterns
Implement the Command pattern with undo. How does encapsulating a request as an object enable queues, logging, and undo/redo? - State — behavior driven by a state machine Behavioral Patterns
Implement the State pattern / a finite state machine. How does it replace scattered boolean flags and guard the transitions a UI can make?
Hard
- Implement Promise.all Implement from scratch
Implement Promise.all(promises): resolve with an array of results in order, or reject on the first rejection. - Implement memoize Implement from scratch
Write a generic memoize(fn) that caches results by arguments. - Proxy and Reflect Metaprogramming
What is a Proxy? What are traps, and how does Reflect complement it? Give a real use case. - Async iterators & for-await-of Async Iteration
How do async iterators and for-await-of work? Implement an async generator that paginates an API.
Other topics
HTML/CSS · Browser · TypeScript · React · System Design · Accessibility · Web Performance · Testing · Networking/Security · DSA