Skip to main content

JavaScript Interview Questions for 2026: 45+ Questions on Closures, the Event Loop, Promises, this-Binding, and the Live-Coding Tasks Interviewers Actually Ask

JavaScript interview questions in 2026 cluster into three buckets: language internals (closures, the event loop, prototypal inheritance, this-binding, hoisting), async reasoning (promises, async/await, microtasks), and live coding (debounce, throttle, deep clone, array transforms). The new-grad trap is reciting MDN definitions you can't apply when the follow-up asks why your code logs that value. This guide gives 45+ questions with answer outlines, the live-coding tasks you'll actually face, and how to sound like you've shipped JavaScript instead of memorized it.

By Sam K., Founder, InterviewChamp.AI · Last updated

20 min read

What JavaScript interview questions actually test in 2026

JavaScript interview questions in 2026 test three things in roughly this order: whether you understand the language internals well enough to predict what a snippet logs, whether you can reason about asynchronous ordering without guessing, and whether you can write a small utility from scratch while talking through it. The internals are the floor. The async reasoning is where the trick questions live. The live-coding task is where most front-end rounds are won or lost.

Here is the honest part most prep guides skip. You can know every array method by name and still fail, because the interviewer is not asking you to list methods. They are asking you to explain why a for loop with var logs the same number three times, or why a resolved promise callback runs before a zero-delay setTimeout. Those are comprehension questions disguised as syntax questions. The candidate who internalized closures and the event loop answers them in two sentences. The candidate who memorized definitions stalls.

The 2025-2026 hiring cycle has not been kind to new grads. Front-end and full-stack roles still hire entry-level talent, but the bar on the fundamentals has crept up because hiring managers are filtering a larger applicant pool. A candidate who can describe what a promise is but cannot trace the order of three chained .then callbacks reads as someone who studied for the interview rather than someone who has shipped JavaScript.

What JavaScript interviews test in 2026

Distribution of question types most new-grad candidates report across their JavaScript loops in the 2025-2026 hiring cycle:

  • 40-50% language internals (closures, this-binding, hoisting, prototypal inheritance, equality)
  • 20-30% async reasoning (promises, async/await, microtask versus macrotask ordering)
  • 20-30% live coding (debounce, throttle, deep clone, array transforms, a custom utility)
  • 5-10% framework and ecosystem (modules, the DOM, a question or two about your stack)

The async-reasoning slice is the one most candidates underprepare, and it disproportionately decides outcomes. Output-prediction questions are cheap for an interviewer to ask and brutally diagnostic: either you know the microtask rule or you are guessing. A candidate who nails ten definition questions but cannot order a promise against a timer signals a shallow model. A candidate who fumbles two definitions but traces the event loop cleanly signals the opposite.

The 3 buckets of JavaScript interview questions

Before drilling specific questions, sort the surface area into three buckets. Most candidates over-invest in bucket one and wing buckets two and three.

Bucket 1: Language internals is the floor, not the ceiling. What is a closure. What does this refer to. What is hoisting. How does prototypal inheritance work. These filter out candidates who have only used JavaScript as copy-paste glue. Expect 8-12 of them in a typical loop, often as a quick warm-up before the live-coding portion.

Bucket 2: Async reasoning is where the output-prediction questions live: trace this promise chain, order these logs, rewrite this callback with async/await. These separate candidates who memorized "promises are for async stuff" from candidates who understand the event loop. Expect 2-4 of them, and treat each as heavier than a definition question because it reveals your actual mental model.

Bucket 3: Live coding is an implement-from-scratch prompt: write debounce, write throttle, deep-clone this object, flatten this nested array, implement a promise-based sleep. These test whether you can turn the internals into working code under observation. Expect 1-2 of them, and know that a clean live-coding pass while narrating your thinking can carry a round even if a couple of definitions wobbled.

Honest call: if you only have a weekend, split it between bucket two and bucket three. Trace ten async snippets out loud, then implement debounce and throttle until they are automatic. Bucket-one definitions are what most candidates over-prepare. Async ordering and live-coding fluency are what most candidates wing.

Key terms

Closure
A function bundled with the variables from the scope where it was defined, so it retains access to them even after the outer function returns. It is the mechanism behind data privacy, stateful callbacks, and the classic loop-variable bug.
Event loop
The runtime mechanism that lets single-threaded JavaScript handle async work by draining the microtask queue completely, then taking one macrotask, then repeating, each time the call stack empties.
Prototypal inheritance
The model where objects delegate property lookups up a chain of prototype links until the property is found or the chain ends at null, which is what the ES6 class syntax compiles down to.
this-binding
The rule that the value of this is decided by how a function is called (plain call, method call, new, or explicit bind), with arrow functions opting out and capturing this from their surrounding scope instead.
Hoisting
The engine's processing of declarations before execution: function declarations are fully available early, var exists as undefined until its assignment runs, and let and const sit in the temporal dead zone until declared.
Microtask queue
The high-priority callback queue for resolved promises and queueMicrotask, drained entirely before the event loop processes the next macrotask such as a timer.

A few more definitions worth saying out loud in the room. Strict equality is the comparison that checks both value and type and never coerces, which is why a number and a numeric string are never equal under it. The temporal dead zone is the window between a let or const entering scope and its declaration line executing, during which reading the variable throws a ReferenceError. Debounce is a wrapper that delays a function until a quiet period elapses, distinct from throttle, which guarantees a function runs at most once per fixed interval no matter how often it is invoked.

JavaScript language-internals questions (15 Q)

The questions below cover the surface area of an entry-level JavaScript interview. Memorize the answer outlines, then adapt the language to your own voice. The structure is the load-bearing part, not the exact words.

Closures and scope (4 Q)

Q1. What is a closure and give a practical use.

A closure is a function plus the variables it captured from its defining scope, kept alive after the outer function returns. Practical use: a counter factory where the returned function increments a private count that nothing outside can touch. That is the module pattern in miniature, the original way JavaScript did data privacy before #private class fields existed.

Q2. Why do all the functions in this loop log the same value?

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0);
}
// logs 3, 3, 3

Because var is function-scoped, so all three arrow functions close over the same binding of i. By the time the timers fire, the loop has finished and i is 3. Swap var for let and you get 0, 1, 2, because let creates a fresh binding each iteration. This is the single most common closure question and the answer that proves you actually understand them.

Q3. How would you fix the loop above without using let?

Wrap the body in an IIFE that takes i as an argument, creating a new scope per iteration:

for (var i = 0; i < 3; i++) {
  (function (j) {
    setTimeout(() => console.log(j), 0);
  })(i);
}
// logs 0, 1, 2

The interviewer is checking whether you understand that the fix is about creating a new binding per iteration, which the IIFE does by passing i as a fresh parameter j.

Q4. What is the module pattern and why was it used?

An IIFE that returns an object exposing only chosen functions, keeping everything else as private variables in the closure. Before ES modules, it was the standard way to avoid polluting the global namespace and to hide implementation details. Knowing it signals you understand the problem ES modules later solved at the language level.

this-binding (3 Q)

Q5. What does this refer to and what are the four rules?

this is set by call-site, not definition-site. Plain call: this is undefined in strict mode. Method call: this is the object before the dot. new call: this is the new instance. Explicit binding via call, apply, or bind: this is whatever you pass. Arrow functions ignore all four and inherit this from the enclosing scope.

Q6. Why does this code lose this and how do you fix it?

const user = {
  name: "Jordan",
  greetLater() {
    setTimeout(function () {
      console.log(this.name); // undefined
    }, 100);
  },
};

The inner function is called as a plain function by the timer, so its this is not user. Fixes: use an arrow function for the callback so it captures this from greetLater, or bind(this), or capture const self = this in the outer scope. The arrow-function fix is the modern default and is the reason arrows were introduced.

Q7. What is the difference between call, apply, and bind?

All three set this explicitly. call invokes the function immediately with arguments listed individually. apply invokes immediately with arguments as an array. bind does not invoke; it returns a new function with this permanently fixed, which you call later. Mnemonic: apply takes an array, call takes a comma list, bind is for binding and later.

Hoisting and equality (4 Q)

Q8. What is hoisting and how does it differ across var, let, const, and functions?

Function declarations are fully hoisted, callable above their definition. var hoists the declaration as undefined, so reading it early gives undefined rather than throwing. let and const hoist into the temporal dead zone, so reading them before declaration throws a ReferenceError. Function expressions assigned to var follow the var rule, not the function-declaration rule.

Q9. What does this log and why?

console.log(a); // undefined
var a = 1;
console.log(b); // ReferenceError
let b = 2;

a is hoisted as undefined, so the first log prints undefined. b is in the temporal dead zone until its declaration, so the second log throws. This snippet is a compact way for an interviewer to test both hoisting and the temporal dead zone in one shot.

Q10. What is the difference between == and ===?

Strict equality compares value and type with no coercion. Loose equality coerces to a common type first, producing surprises like "" == 0 being true and null == undefined being true. The 2026 rule: use === everywhere; reach for == only for a single value == null check that catches both null and undefined. Most linters flag == by default.

Q11. What is the difference between null and undefined?

undefined means a variable was declared but never assigned, or a missing property or argument. null is an intentional empty value you assign yourself to say "no value here." typeof undefined is "undefined"; typeof null is the famous historical bug that returns "object". Use undefined for absence the engine produces, null for absence you choose.

Prototypes and ES6+ (4 Q)

Q12. Explain prototypal inheritance and the prototype chain.

Every object links to a prototype object. Reading a missing property walks up the chain until found or until the chain hits null. Constructor functions and classes attach shared methods to a prototype object so instances share one copy instead of each carrying its own. Classes are syntactic sugar over this; there is no separate classical-inheritance system underneath.

Q13. How does an ES6 class relate to prototypes?

A class compiles to a constructor function plus methods on its prototype. extends sets up the prototype chain between child and parent, and super calls the parent constructor or method. The takeaway interviewers want: class is readability sugar, not a new inheritance model. If you can say that, you have shown you know what is happening underneath.

Q14. Which ES6+ features do you use most and why?

Arrow functions for concise callbacks and lexical this. const and let for block scoping. Template literals for readable string building. Destructuring and the spread and rest operators for clean data handling. async/await for readable async code. Optional chaining and nullish coalescing for safe property access. The honest answer names a handful you genuinely reach for, not the entire changelog.

Q15. What is the difference between the spread and rest operators?

Same three-dot syntax, opposite jobs depending on position. Spread expands an iterable into individual elements, used to copy or merge arrays and objects. Rest collects remaining items into an array, used in function parameters or destructuring. In const [first, ...others] = arr, the three dots are rest. In fn(...arr), they are spread.

JavaScript async interview questions (10 Q)

Async reasoning is where the entry-level JavaScript interview separates real understanding from memorized vocabulary. Each question below is the kind interviewers use to probe your event-loop model.

Q16. How does the event loop work?

One call stack runs synchronous code to completion. Async callbacks wait in queues. When the stack empties, the loop drains the entire microtask queue (promise callbacks), then takes one macrotask (a timer or I/O callback), then repeats. The single-thread-plus-event-loop model is why JavaScript is concurrent without being parallel.

Q17. What does this log, and in what order?

console.log("A");
setTimeout(() => console.log("B"), 0);
Promise.resolve().then(() => console.log("C"));
console.log("D");
// A, D, C, B

A and D are synchronous, so they print first in source order. C is a microtask, drained before any macrotask. B is a macrotask (timer), so it runs last even at zero delay. If you can explain this ordering, you have answered the single most-asked async question.

Q18. What is the difference between microtasks and macrotasks?

Microtasks (promise .then callbacks, queueMicrotask) have priority and the loop drains all of them before moving on. Macrotasks (setTimeout, setInterval, I/O, UI events) run one per loop iteration. The practical consequence: a chain of resolved promises all completes before a zero-delay timer fires.

Q19. What is a promise and what are its three states?

A promise is an object representing the eventual result of an async operation. Its states are pending, fulfilled (resolved with a value), and rejected (failed with a reason). Once it settles to fulfilled or rejected, it never changes again. You consume it with .then, .catch, and .finally, or with async/await.

Q20. What is the difference between async/await and .then chains?

They do the same thing; async/await reads as synchronous top-to-bottom code. An async function always returns a promise, and await pauses inside it until the awaited promise settles. Error handling moves from .catch to try/catch. The catch interviewers probe: await only pauses the async function, not the whole thread, so the event loop keeps serving other work.

Q21. How do you run async operations in parallel?

Promise.all takes an array of promises and resolves when all settle, rejecting fast if any one rejects. Promise.allSettled waits for every promise and reports each outcome without short-circuiting. Use Promise.all when you need every result and any failure should abort. Use Promise.allSettled when partial success is acceptable. Awaiting promises one by one in a loop runs them serially, which is the common performance mistake.

Q22. What is the difference between Promise.all, Promise.race, and Promise.any?

Promise.all resolves when all resolve, rejects on the first rejection. Promise.race settles as soon as the first promise settles, resolve or reject. Promise.any resolves on the first fulfillment and only rejects if all reject. race suits timeouts (race your request against a timer). any suits "first successful source wins."

Q23. How would you implement a promise-based sleep?

const sleep = (ms) =>
  new Promise((resolve) => setTimeout(resolve, ms));

// usage
await sleep(500);

Wrap a setTimeout in a promise that resolves when the timer fires. This is a frequent warm-up because it tests whether you understand that promises wrap callback-based APIs. The follow-up is often "now add a value to resolve with" or "now make it rejectable."

Q24. What happens if you forget to handle a rejected promise?

The rejection becomes an unhandled promise rejection. In browsers it logs a warning and fires an unhandledrejection event. In Node it logs a warning and, in recent versions, can crash the process by default. The fix is always to attach a .catch or wrap the await in try/catch. Interviewers ask this to confirm you treat error paths as first-class, not an afterthought.

Q25. Is JavaScript single-threaded or multi-threaded?

Execution is single-threaded: one call stack, one operation at a time. Concurrency comes from the event loop offloading async work to the host and queuing callbacks. For real parallelism you use Web Workers in the browser or worker threads in Node, separate threads that communicate by message passing. The precise answer: single-threaded execution, concurrent via the event loop, parallel only through workers.

JavaScript live-coding interview tasks (8 Q)

Live coding is where the internals become working code under observation. Each task below shows up across front-end loops because each one packs several concepts into a few lines. Rehearse them until the structure is automatic, then narrate as you type in the real round.

Q26. Implement debounce.

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

A closure holds timer between calls. Every invocation clears the pending timer and sets a new one, so fn only runs after delay of silence. Mention the use case (search-as-you-type) and the this/args forwarding, which is the detail weaker candidates drop.

Q27. Implement throttle.

function throttle(fn, interval) {
  let last = 0;
  return function (...args) {
    const now = Date.now();
    if (now - last >= interval) {
      last = now;
      fn.apply(this, args);
    }
  };
}

Track the last-run timestamp in the closure and only run again once interval has passed. Contrast it with debounce out loud: throttle fires at a steady cadence during continuous activity (scroll, resize); debounce waits for the activity to stop.

Q28. Implement a deep clone.

function deepClone(value) {
  if (value === null || typeof value !== "object") return value;
  if (Array.isArray(value)) return value.map(deepClone);
  return Object.fromEntries(
    Object.entries(value).map(([k, v]) => [k, deepClone(v)])
  );
}

Recurse through objects and arrays, copying primitives directly. Call out the limitations: this version skips Date, Map, Set, and circular references, and note that structuredClone is the modern built-in that handles most of those. Naming the trade-off is the senior signal.

Q29. Flatten a nested array.

function flatten(arr) {
  return arr.reduce(
    (acc, item) =>
      acc.concat(Array.isArray(item) ? flatten(item) : item),
    []
  );
}

Recurse with reduce, flattening nested arrays and concatenating values. Mention that the built-in arr.flat(Infinity) does this in one call; implementing it by hand is what tests your recursion and array fluency.

Q30. Implement your own map.

function myMap(arr, fn) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    result.push(fn(arr[i], i, arr));
  }
  return result;
}

Loop, apply the callback to each element, push the result. The detail that earns points: passing (element, index, array) to the callback, matching the real signature. It shows you have read how the built-in actually works.

Q31. Group an array of objects by a key.

function groupBy(items, key) {
  return items.reduce((acc, item) => {
    const group = item[key];
    (acc[group] ||= []).push(item);
    return acc;
  }, {});
}

Reduce into an object keyed by the chosen field. This is a realistic data-shaping task that mirrors everyday front-end work, so interviewers like it more than pure-algorithm puzzles for entry-level roles.

Q32. Implement a simple event emitter.

class Emitter {
  constructor() {
    this.handlers = {};
  }
  on(event, fn) {
    (this.handlers[event] ||= []).push(fn);
  }
  emit(event, ...args) {
    (this.handlers[event] || []).forEach((fn) => fn(...args));
  }
}

Store handler arrays keyed by event name; emit calls each one with the forwarded arguments. It tests objects, arrays, and the publish-subscribe pattern that underlies a lot of front-end and Node code. Add an off method if the interviewer pushes further.

JavaScript framework and ecosystem questions (5 Q)

Full-stack and front-end loops add a few questions on modules, the DOM, and your stack. Five worth rehearsing.

Q33. What is the difference between CommonJS and ES modules?

CommonJS (require/module.exports) is Node's original synchronous module system, resolved at runtime. ES modules (import/export) are the standardized system, statically analyzable, supporting tree-shaking and top-level await. As of 2026 ES modules are the default for new front-end and most new Node code, with CommonJS lingering in older packages. Knowing both exist and why ESM won is the expected answer.

Q34. What is event delegation in the DOM?

Attach one listener to a parent element instead of many listeners to each child, then use event.target to figure out which child was hit. It relies on event bubbling. The payoff: fewer listeners, and it automatically covers child elements added later. It is a classic front-end question because it tests both DOM events and a performance instinct.

Q35. What is the difference between let shadowing and a closure leak?

A common confusion the interviewer may probe. Block scoping with let shadows an outer variable safely inside a block. A closure leak is when a closure unintentionally retains a large object longer than needed, keeping it from garbage collection. The fix for the leak is to null out the reference or restructure so the closure only captures what it needs.

Q36. How does JSON.stringify handle special values?

It drops undefined, functions, and symbols when they are object property values, and converts them to null inside arrays. It serializes Date objects to ISO strings via their toJSON. It throws on circular references. Knowing these edge cases matters because naive serialization is a frequent source of "why did my field disappear" bugs.

Q37. What is the difference between shallow and deep copy?

A shallow copy (spread, Object.assign) duplicates the top level but shares nested object references, so mutating a nested value affects both copies. A deep copy duplicates every level so the two are fully independent. The interview-relevant follow-up is usually "show me how to deep copy," which loops back to the deepClone or structuredClone answer from the live-coding section.

JavaScript interview format by role type

The same JavaScript surface area gets tested differently depending on the role. The breakdown for the four most common JavaScript-heavy roles hiring new grads in 2026:

RoleInternals depthAsync weightLive-coding styleFramework focusWhat carries the round
Front-end EngineerHigh (this, closures, prototypes)MediumDOM utilities (debounce, throttle, event emitter)High (React/Vue patterns, rendering)Clean live coding plus internals fluency
Full-stack EngineerMedium-HighHigh (promises, Promise.all)Mixed (array transforms, async helpers)Medium (Node, ES modules)Balanced internals and async reasoning
Node / Backend EngineerMediumHigh (event loop, streams, error paths)Data shaping (groupBy, parsing)Medium (modules, async patterns)Async correctness and error handling
SWE with JS as primary languageHighMediumAlgorithm-flavored (recursion, two-pointer in JS)LowAlgorithm rounds plus internals spot-checks

Two patterns to notice. First, every JavaScript-heavy role tests closures, this, and the event loop; those are universal. Second, the live-coding style shifts: front-end loops favor DOM-flavored utilities, backend loops favor data shaping and async correctness, and pure-SWE loops lean algorithmic with JavaScript as the medium. Matching your prep to the role's live-coding style matters more than most candidates realize.

How to prepare for a JavaScript interview as a CS new grad

A focused two-week plan, calibrated for a new grad whose JavaScript is at the "I can build things but freeze on why-does-this-log questions" starting point. Adjust if you are further along.

  1. Week 1, days 1-3: Drill the internals by predicting output. Write your own snippets for closures, hoisting, the temporal dead zone, and this-binding. Before running each, write down what you think it logs, then run it. The gap between prediction and reality is exactly what an interviewer will probe. Keep a list of every snippet that surprised you and re-test it two days later.

  2. Week 1, days 4-5: Master the event loop and async ordering. Take five mixed snippets combining synchronous logs, a zero-delay timer, and a resolved promise callback. Predict the order. The rule you are cementing is that the microtask queue drains completely before the next macrotask. Once you order setTimeout against Promise.resolve().then correctly every time, you have closed the most-tested async gap, then layer in async/await.

  3. Week 1, days 6-7: Rehearse the live-coding utilities from scratch. Implement debounce, throttle, a deep clone, a promise-based sleep, and a flatten on a blank editor with no autocomplete. Aim for under three minutes each. These reappear constantly because they pack closures, timers, recursion, and promises into a few lines. Write each at least three times across the week until the structure is muscle memory.

  4. Week 2, days 8-10: Drill array transforms and ES6+ fluency. Practice map, filter, reduce, and the spread and rest operators until you reach for them without thinking. Re-solve five small array problems using only these methods, then again with destructuring in the parameters. Interviewers read fluent modern syntax as proof you write JavaScript daily.

  5. Week 2, days 11-12: Take a timed mock round narrating out loud. Run a 45-minute mock mixing ten internals questions with one live-coding task. Narrate the entire time, the way you would in the real interview. Record yourself or use an AI-driven mock tool. The first run exposes which explanations are still mushy. If you want on-demand JavaScript prompts and a quiet answer outline to react to so you can hear yourself explain a closure before it counts, run a mock JavaScript round in the live interview assistant and walk into your real round able to say the answer instead of recognizing it.

  6. Week 2, days 13-14: Patch your weakest two topics and re-test. Pull your surprise-snippet list and your mock recording. Pick the two topics you fumbled most, almost always this-binding and async ordering for new grads, and drill only those. Re-run a short focused mock to confirm the fix held. A live interview assistant you can start for a $3 trial gives you unlimited JavaScript reps and a structured answer outline to react to, so the rep cost is a coffee instead of a friend's afternoon.

The non-negotiable block is days 1-5. Output-prediction questions are the fastest filter interviewers have, and there is no shortcut for the calibration that comes from predicting a snippet, being wrong, and understanding why.

Common JavaScript interview mistakes for new grads

The five most-reported mistakes from new-grad JavaScript interviews in the 2025-2026 hiring cycle, in rough order of frequency:

Reciting definitions you cannot apply. A candidate who says "a closure is a function with access to its outer scope" but cannot explain the var-loop logging bug has memorized words, not a model. The fix: stop reading definitions and start predicting snippet output, because that is the form the question actually takes.

Guessing on async ordering instead of reasoning. Many candidates hand-wave the order of a promise-versus-timer snippet and hope. Interviewers read the hesitation instantly. The fix: drill the microtask-drains-before-the-next-macrotask rule on five snippets until you state the order with zero hesitation.

Dropping this and argument forwarding in live coding. Candidates implementing debounce or throttle often forget to forward this and args to the wrapped function, which works in a toy demo but breaks on a real method. The fix: bake fn.apply(this, args) into your muscle memory so it comes out automatically.

Confusing == and === under pressure. Reaching for loose equality, then getting tripped by a coercion edge case, is a needless self-inflicted wound. The fix: default to === everywhere and only ever use == for the single value == null idiom, the same rule your linter enforces.

Over-explaining the easy questions and under-explaining the hard ones. New grads often spend ninety seconds on "what is let" and then rush the event-loop answer that actually decides the round. The fix: answer definitions in two crisp sentences and spend your airtime on the comprehension questions where depth is the differentiator.

One thing I would add from watching new grads run JavaScript rounds: do not try to cram all five fixes the night before. Pick the two that match your gaps (almost always async ordering and this-binding) and close those. The other three resolve themselves once the foundation is solid.

Related guides


About the author: Sam K. is the founder of InterviewChamp.AI, building AI interview prep for the new-grad CS market and writing about the modern interview gauntlet from the inside.

Related guides

Interview Process

DevOps Interview Questions for 2026: 45+ Questions Across CI/CD, IaC, Observability, Kubernetes, Deployments, SRE, and Incident Response

DevOps interview questions in 2026 cluster into six areas: CI/CD pipelines, infrastructure-as-code, monitoring and observability, containers and orchestration, deployment strategies (blue-green and canary), and the SRE plus incident-response thinking that ties them together. The new-grad gap is reasoning about production trade-offs you've never owned on call. This guide gives 45+ questions across those areas, the culture questions interviewers slip in, and the honest framing that works when you've never carried a pager.

Sam K. ·

Read more →
Interview Process

Docker Interview Questions for 2026: 40+ Q's Across Images vs Containers, the Layer Cache, Dockerfiles, Volumes, Networking, Compose, and the Orchestration Intro New Grads Get Wrong

Docker interview questions in 2026 split between definition recall (what's an image vs a container, what's a layer) and the build-and-debug scenarios that separate the candidate who ran `docker run` once from the one who actually shipped a containerized app. Expect questions on the layer cache, Dockerfile authoring, volumes, networking, docker-compose, multi-stage builds, containers vs VMs, and a closing intro to orchestration. This guide gives 40+ questions with answer outlines and a three-week prep plan that doesn't ask you to fake production experience.

Sam K. ·

Read more →
Interview Process

Node.js Interview Questions for 2026: 45+ Questions on the Event Loop, Streams, Async Patterns, Cluster, and Backend Security

Node.js interview questions in 2026 cluster around five things: the event loop and libuv, async patterns plus error handling, streams and backpressure, scaling with cluster and worker threads, and backend security basics. The new-grad gap is explaining how the single-threaded runtime stays fast under load. This guide gives 45+ questions with answer outlines across the event loop, streams, middleware, EventEmitter, package management, and security, plus the prep plan that makes the answers stick.

Sam K. ·

Read more →

Frequently asked questions

What JavaScript interview questions should I expect in 2026?
Expect three buckets. Language internals (40-50% of questions) tests closures, the event loop, prototypal inheritance, this-binding, hoisting, and equality. Async reasoning (20-30%) tests promises, async/await, and the microtask versus macrotask ordering that produces those trick console-log questions. Live coding (20-30%) asks you to implement something small from scratch: debounce, throttle, a deep clone, a promise-based sleep, or a custom array method. Front-end-leaning loops weight internals and live coding heavily. Full-stack and Node loops add async and module questions.
What is a closure in JavaScript and why do interviewers ask about it?
A closure is a function bundled with the variables from the scope where it was defined, so it keeps access to those variables even after the outer function has returned. Interviewers ask because closures explain data privacy (module pattern), stale-value bugs in loops, and how callbacks remember state. The classic test is a for-loop creating functions: with var the closures share one binding and all log the final value, while let creates a fresh binding per iteration. If you can explain that difference, you understand closures.
How does the JavaScript event loop work?
JavaScript runs on a single thread with a call stack. Synchronous code runs first to completion. Asynchronous callbacks wait in two queues: the microtask queue (promise callbacks, queueMicrotask) and the macrotask queue (setTimeout, setInterval, I/O). After the stack empties, the event loop drains the entire microtask queue before taking one macrotask, then repeats. This is why a resolved promise callback runs before a zero-delay timer. Knowing the microtask-before-macrotask rule is what lets you predict the output of the ordering questions interviewers love.
What is the difference between == and === in JavaScript?
The triple-equals operator compares value and type with no coercion, so a number and a string are never equal. The double-equals operator coerces operands to a common type before comparing, which produces surprising results like an empty string equaling zero or null loosely equaling undefined. The 2026 consensus is to use strict equality everywhere and reach for loose equality only in the one idiomatic case: a single null check that also catches undefined. Most style guides and linters flag loose equality by default.
What is the difference between var, let, and const?
All three declare variables, but they differ on scope, hoisting, and reassignment. The var keyword is function-scoped and hoisted with an initial value of undefined. The let and const keywords are block-scoped and hoisted into a temporal dead zone, so reading them before declaration throws. The const keyword forbids reassignment of the binding, though the object it points to can still be mutated. As of 2026 the standard advice is const by default, let when you must reassign, and var almost never in new code.
What does this refer to in JavaScript?
The this keyword is set by how a function is called, not where it is defined. A plain function call sets this to undefined in strict mode or the global object otherwise. A method call sets this to the object before the dot. The new keyword sets this to the freshly created instance. The call, apply, and bind methods set it explicitly. Arrow functions are the exception: they capture this from the surrounding scope and ignore all of the above, which is exactly why they fixed the old callback this-loss bug.
What is hoisting in JavaScript?
Hoisting is how the engine processes declarations before executing code. Function declarations are fully hoisted, so you can call them above where they appear. The var keyword hoists the declaration but not the assignment, so the name exists as undefined until the assignment line runs. The let and const keywords are hoisted into the temporal dead zone, where accessing them throws a ReferenceError until the declaration executes. Understanding hoisting explains why some code runs and some throws, which is a common follow-up after the closure question.
How do you implement debounce and throttle in JavaScript?
Both limit how often a function runs, but differently. Debounce delays execution until a quiet period passes, so a search box only fires after the user stops typing for, say, 300 milliseconds. You clear and reset a timer on every call. Throttle guarantees a function runs at most once per interval no matter how often it is called, which suits scroll and resize handlers. You track the last-run timestamp or use a cooldown flag. Implementing both from scratch is one of the most common front-end live-coding tasks, so rehearse them until you can write each in under three minutes.
What are the most important ES6+ features for a JavaScript interview?
The high-frequency set is arrow functions, let and const, template literals, destructuring, the spread and rest operators, default parameters, promises and async/await, ES modules (import and export), and classes. Newer additions worth knowing are optional chaining, nullish coalescing, and array methods like flatMap. Interviewers care less about reciting the list and more about whether you reach for destructuring and spread naturally during live coding. Using them fluently signals you write modern JavaScript day to day.
What is prototypal inheritance in JavaScript?
Every object has a hidden link to another object called its prototype. When you read a property that does not exist on the object, the engine walks up the prototype chain until it finds the property or reaches null. Functions get a prototype object whose members are shared by all instances created with the new keyword. The class syntax added in ES6 is sugar over this same mechanism: it does not introduce classical inheritance, it just makes the prototype wiring more readable. Interviewers probe this to see whether you understand what classes actually compile to.
How should a CS new grad prepare for a JavaScript interview in 2026?
Spend two focused weeks. Week one drills the internals: write closure, hoisting, and this-binding examples by hand and predict their output before running them. Week two drills live coding: implement debounce, throttle, deep clone, a promise-based sleep, and two or three array transforms from scratch, then do timed mock rounds where you narrate your reasoning out loud. The differentiator at the entry level is not how many methods you have memorized. It is whether you can predict what a snippet logs and write a small utility cleanly while talking through it.
Is JavaScript single-threaded or multi-threaded?
JavaScript execution is single-threaded: one call stack, one thing running at a time. Concurrency comes from the event loop offloading async work (timers, network, I/O) to the host environment and queuing the callbacks for later. For true parallelism you reach outside the language to Web Workers in the browser or worker threads in Node, which run separate threads with their own stacks and communicate by message passing. Saying JavaScript is single-threaded but concurrent via the event loop is the precise answer interviewers want.