Skip to main content
← All posts

45 JavaScript Interview Questions That Reveal Skill

·Intervy Team·13 min read
45 JavaScript Interview Questions That Reveal Skill
On this page

Most JavaScript interview questions floating around the internet test memorization, not skill. Asking "what's the difference between == and ===?" tells you nothing about whether a candidate can debug a race condition in production or architect a clean module system. The questions you ask should create a gradient — easy enough for juniors to show fundamentals, deep enough for seniors to demonstrate mastery. This guide highlights 24 of the best JavaScript interview questions from our full set of 45, organized by topic and difficulty, with guidance on what separates average answers from great ones.

TL;DR: 24 highlighted JavaScript interview questions from our bank of 45, across 6 categories — fundamentals, async patterns, ES6+ features, coding challenges, and common pitfalls — with reference answers, scoring rubrics, and ready-to-use interview formats.


Core JavaScript Fundamentals Every Interviewer Should Test

These questions form the foundation. Every JavaScript developer — junior through senior — should handle these topics. The depth of their answers is what reveals the level.

Closures and Scope

Closures are the single most revealing JavaScript concept. A candidate who truly understands closures can reason about hooks, callbacks, memoization, and module patterns.

function createCounter() { let count = 0; return { increment: () => ++count, getCount: () => count, }; } const counter = createCounter(); counter.increment(); counter.increment(); console.log(counter.getCount()); // 2

What is a closure? Give a real-world example where closures solve a problem.

A basic answer defines closure as a function retaining access to its lexical scope. A great answer explains why this matters — data privacy, factory functions, partial application — and gives a concrete example like event handler factories or the module pattern.

Explain the difference between var, let, and const in terms of scope and hoisting.

Look for more than "let and const are block-scoped." Strong candidates explain the temporal dead zone, why var hoists to the function scope, and when const doesn't actually prevent mutation (objects and arrays).

How does the this keyword work in JavaScript? What changes its value?

This question has surprising depth. Good answers cover the four binding rules: default, implicit, explicit (call/apply/bind), and new. Great answers add arrow function behavior — lexical this — and explain why arrow functions can't be used as constructors.

Tip: Follow up with "What does this refer to inside a setTimeout callback?" to test whether they understand default binding vs lexical binding in practice.

Prototypes and Inheritance

Explain prototypal inheritance. How does it differ from classical inheritance?

Candidates should describe the prototype chain — objects delegate to other objects, not classes. A strong answer mentions Object.create(), explains __proto__ vs .prototype, and acknowledges that ES6 classes are syntactic sugar over prototypes.

What happens when you access a property that doesn't exist on an object?

The answer reveals whether they understand prototype chain traversal. JavaScript walks up the chain through __proto__ links until it reaches Object.prototype, then returns undefined. Senior candidates mention performance implications of deep prototype chains.

Type Coercion

Why does [] == false return true but [] == 0 also return true?

This is less about memorizing the abstract equality algorithm and more about revealing whether a candidate has been burned by implicit coercion in production. The best answers explain why strict equality should be the default and when loose equality is actually intentional (like value == null for null/undefined checks).

Key takeaway: Fundamental questions should be layered. Start simple, then probe deeper based on the answer. A closure question that starts with definition should escalate to practical applications and edge cases.


Async JavaScript and the Event Loop

Asynchronous JavaScript is where junior developers get stuck and senior developers shine. These questions test mental models, not just syntax.

Event Loop Mechanics

Understanding the event loop separates developers who write async code from developers who debug it. Use this code block as a discussion starter:

console.log('1'); setTimeout(() => console.log('2'), 0); Promise.resolve().then(() => console.log('3')); queueMicrotask(() => console.log('4')); console.log('5'); // Output: 1, 5, 3, 4, 2

Explain the JavaScript event loop. What's the difference between microtasks and macrotasks?

The baseline: JavaScript is single-threaded, uses a call stack, and offloads async work to the browser/runtime. Good answers explain that microtasks (promises, queueMicrotask, MutationObserver) drain completely before the next macrotask (setTimeout, setInterval, I/O). Great answers mention that this is why a recursive microtask can block rendering.

What is the output of the code above? Explain why.

Walk through it step by step. 1 and 5 are synchronous. Then the microtask queue drains: 3 (Promise.then) and 4 (queueMicrotask). Finally the macrotask: 2 (setTimeout). Candidates who get the order right and explain why understand the runtime.

Tip: If a candidate nails this, follow up with: "What happens if you nest a setTimeout(0) inside a Promise.then?" This tests whether they understand microtask priority at a deeper level.

Promises and Async/Await

What are the three states of a Promise? Can a settled Promise change state?

Pending, fulfilled, rejected. Once settled, a Promise cannot change — this immutability is a core design decision. Senior candidates mention that this guarantee is what makes .then() chaining safe.

How does error handling differ between .catch() and try/catch with async/await?

Both catch rejections, but the patterns differ. A common mistake is forgetting that await outside a try block produces an unhandled rejection. Strong candidates explain the Promise.allSettled pattern for handling partial failures in parallel operations.

What is Promise.allSettled and when would you use it over Promise.all?

Promise.all short-circuits on the first rejection. Promise.allSettled waits for all promises and reports each result. The practical use case — batch API calls where you want partial results — separates developers who've built real async systems from those who haven't.

Key takeaway: Async questions reveal debugging ability. Developers who can trace execution order through the event loop can diagnose the hardest category of JavaScript bugs.


ES6+ Features Worth Testing in 2026

Modern JavaScript has evolved far beyond arrow functions and template literals. These questions test whether candidates keep up with the language and use newer features appropriately.

Destructuring and Spread

Explain destructuring with default values and renaming. When does destructuring hurt readability?

Basic: const { name: userName = 'Anonymous' } = user. Good answers demonstrate nested destructuring and array destructuring. Great answers acknowledge the readability trade-off — deeply nested destructuring is harder to read than explicit property access.

Modules and Code Organization

What's the difference between named exports and default exports? Which do you prefer and why?

Named exports enable tree-shaking and make refactoring safer (rename propagates). Default exports are convenient but hide the actual export name. Senior candidates have an opinion backed by experience, not just convention.

Advanced ES6+ Patterns

Explain WeakMap and WeakSet. Give a use case that Map and Set can't handle.

The key insight: weak references allow garbage collection. Use cases include storing metadata on DOM elements without preventing cleanup, or caching computed values tied to object lifetimes. Candidates who mention memory leak prevention in long-running applications show real-world awareness.

What are generators? When would you use one over an async function?

Generators produce values lazily with yield. Practical uses include paginated data iteration, infinite sequences, and custom async flow control. A great answer contrasts generators with async iterators (for await...of) and explains when each fits.

How does Proxy work? Give an example of where you'd use it in production.

Proxy intercepts fundamental operations (get, set, has, delete) on objects. Production use cases include validation layers, reactive state systems (like Vue's reactivity), logging, and API response transformation. This is a senior-level question — most mid-level developers haven't used Proxy directly.

const validator = new Proxy( {}, { set(target, prop, value) { if (prop === 'age' && typeof value !== 'number') { throw new TypeError('Age must be a number'); } target[prop] = value; return true; }, }, ); validator.age = 25; // works validator.age = 'twenty-five'; // throws TypeError

Technical interview preparation tool showing JavaScript questions organized by category, tags, and difficulty levels


Practical JavaScript Coding Challenges

Trivia tests memory. Coding challenges test thinking. These problems reveal how a candidate approaches implementation, handles edge cases, and writes clean code.

Implementation Challenges

Implement a debounce function.

This is the gold standard for JavaScript coding challenges. It tests closures, setTimeout, and this binding in a single problem.

function debounce(fn, delay) { let timeoutId; return function (...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => fn.apply(this, args), delay); }; }

What to look for: Does the candidate handle this context? Do they use clearTimeout correctly? Can they extend it with an immediate option or a cancel method? Senior developers will mention the leading vs trailing edge distinction.

Implement a deep clone function without using structuredClone.

function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Date) return new Date(obj); if (obj instanceof RegExp) return new RegExp(obj); if (Array.isArray(obj)) return obj.map(deepClone); return Object.fromEntries( Object.entries(obj).map(([key, val]) => [key, deepClone(val)]), ); }

What to look for: Does the candidate handle special types (Date, RegExp, Map, Set)? Do they mention circular reference detection? A great answer discusses when to use structuredClone() instead and its limitations (no functions, no DOM nodes).

Tip: After the implementation, ask "What would break if the object has circular references?" This reveals whether they think about edge cases proactively.

Flatten a nested array to arbitrary depth.

function flatten(arr, depth = Infinity) { return depth > 0 ? arr.reduce( (acc, val) => acc.concat(Array.isArray(val) ? flatten(val, depth - 1) : val), [], ) : arr.slice(); }

What to look for: Do they know about Array.prototype.flat()? Can they implement it recursively and iteratively? Do they handle the depth parameter? Senior candidates might mention stack overflow risks with deeply nested arrays and suggest an iterative approach using a stack.

Write a function that retries a failed async operation with exponential backoff.

This tests async patterns, error handling, and practical API interaction skills.

async function retry(fn, maxRetries = 3, baseDelay = 1000) { for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await fn(); } catch (err) { if (attempt === maxRetries) throw err; await new Promise((r) => setTimeout(r, baseDelay * 2 ** attempt)); } } }

What to look for: Exponential backoff calculation, proper error propagation on final failure, and whether they mention jitter to prevent thundering herd problems.

Key takeaway: Coding challenges should have layers. The basic implementation is table stakes — follow-up questions about edge cases and extensions reveal the real skill level.


Common JavaScript Pitfalls That Reveal Experience

These questions don't test knowledge — they test battle scars. Developers who've shipped production JavaScript recognize these patterns immediately.

Reference vs Value

What's the output of this code?

const a = { value: 1 }; const b = a; b.value = 2; console.log(a.value); // 2

Simple, but it catches junior candidates who don't understand reference types. Follow up with: "How would you create an independent copy?" to test whether they reach for spread, Object.assign, or structuredClone.

Hoisting Surprises

What's the output and why?

console.log(typeof myFunc); // "function" console.log(typeof myVar); // "undefined" function myFunc() {} var myVar = 'hello';

Function declarations are fully hoisted (name + body). var declarations are hoisted but not their assignments. let and const are hoisted but stay in the temporal dead zone. This question separates developers who understand the compilation phase from those who just memorize rules.

The this Binding Trap

What does this refer to in each case?

const obj = { name: 'Alice', greet: function () { console.log(this.name); }, greetArrow: () => { console.log(this.name); }, }; obj.greet(); // "Alice" obj.greetArrow(); // undefined (or window.name in browser)

Arrow functions don't have their own this — they inherit from the enclosing lexical scope. This is one of the most common sources of bugs when developers mix arrow functions and regular methods on objects and classes.

Tip: If the candidate explains this correctly, follow up with: "What happens if you pass obj.greet as a callback to setTimeout?" This tests implicit binding loss — a real-world bug that trips up even experienced developers.

Comparison Gotchas

Explain why NaN === NaN returns false and how to properly check for NaN.

NaN is the only JavaScript value that is not equal to itself. Number.isNaN() is the correct check — not the global isNaN() which coerces its argument first (isNaN("hello") returns true). This distinction catches developers who haven't dealt with numeric edge cases in data processing.


How to Structure a JavaScript Technical Screen

Knowing the right questions is half the battle. Organizing them into a structured interview format ensures consistent evaluation across candidates and interviewers.

30-Minute Screen Format

A focused screen for initial candidate filtering. Move fast and cover breadth.

  • Minutes 0-2: Introduction — brief role overview, set expectations for the format
  • Minutes 2-10: Fundamentals rapid-fire — 3-4 conceptual questions (closures, this, prototypes) to establish baseline
  • Minutes 10-22: One coding challenge — pick debounce, deep clone, or retry with backoff depending on the role level
  • Minutes 22-28: Async deep dive — event loop question plus one Promise-based scenario
  • Minutes 28-30: Candidate questions — always leave time for this

Tip: Prepare difficulty variants for each question. If a candidate breezes through the junior version, escalate. If they struggle, simplify. The goal is finding their ceiling, not failing them on a fixed bar.

60-Minute Technical Interview

A comprehensive assessment for final rounds. Test depth and breadth.

  • Minutes 0-5: Introduction and warmup — a relaxed fundamentals question to ease nerves
  • Minutes 5-20: Core concepts deep dive — 4-5 questions escalating in difficulty, covering closures, async, and ES6+ features
  • Minutes 20-40: Two coding challenges — one implementation (debounce/clone) and one debugging (pitfall code)
  • Minutes 40-50: Architecture discussion — module organization, error handling strategy, or API design question
  • Minutes 50-55: Candidate questions and discussion
  • Minutes 55-60: Interviewer notes — score immediately while context is fresh

Interview template builder showing reusable JavaScript interview templates with question counts

Building reusable interview templates with an interview template builder ensures every interviewer on your team asks calibrated questions at the right difficulty level.


Scoring JavaScript Interview Answers — What Separates Good from Great

Consistent scoring eliminates the "gut feeling" problem. Intervy uses a 5-point scale for every question.

The 5-Point Scale

  • Strong No (1) — the candidate cannot answer or gives fundamentally incorrect information
  • No (2) — partial understanding, but significant gaps or misconceptions
  • Maybe (3) — factually correct but surface-level, no reasoning or practical examples
  • Yes (4) — solid answer with trade-offs, reasoning, or real-world context
  • Strong Yes (5) — exceptional depth — connects concepts, mentions edge cases unprompted, offers alternatives

Scoring in Practice

QuestionMaybe (3)Yes (4)Strong Yes (5)
What is a closure?Defines function + lexical scopeAdds practical exampleDiscusses memory implications, module pattern
Event loop outputGets the order rightExplains micro vs macroMentions rendering blocking, starvation
Implement debounceWorking basic versionHandles this and argsAdds cancel, leading edge, TypeScript types
WeakMap use caseDefines weak referencesGives one use caseExplains GC behavior, compares to Map

Red Flags vs Green Flags

  • Red flag: Answers that start with "I think..." on fundamentals they should know cold
  • Red flag: Cannot explain why something works, only that it works
  • Green flag: Asks clarifying questions before answering ("Are you asking about browser JS or Node?")
  • Green flag: Mentions trade-offs unprompted ("You could use Proxy here, but it has performance overhead")

AI interview question generator Ivy helping prepare JavaScript interview questions

An interview question generator like Ivy can help you quickly build question sets calibrated to specific roles and levels — then score consistently across your team.


Build Your JavaScript Interview Question Bank

Good interviews aren't improvised — they're engineered. The 24 questions in this guide give you a structured foundation, but the full set of 45 covers even more ground. Browse all of them with answers, difficulty ratings, and filtering on our JavaScript interview questions page.

For a broader view of technical interviewing across all roles, see our complete guide to technical interview questions. If you're hiring React developers specifically, check out our React interview questions guide with 30 role-specific questions.

All 45 questions are also available as a ready-to-import set in Intervy. Head to the Export / Import page, select "JavaScript Interview" from the Sample Interview Data dropdown, and click Load — organized by category, tagged by difficulty, and ready to drop into your next interview template.

Related posts