Technology interview warm-up

JavaScript Interview Questions and Answers

JavaScript interview questions and answers hub with coding prompts, concept questions, follow-ups, and common mistakes. Practice concise answers first, then expand into Study Plans, guides, and Company Prep.

Reviewed May 19, 2026FrontendAtlas Editor25 answers, 8 output questions, and 8 browser/DOM/security questions

On this page

Short answers

Top JavaScript interview questions and short answers, beginner to advanced

Use these beginner, intermediate, and advanced answers for a fast review, then open the linked practice route when a topic needs deeper coding or explanation work.

Fundamentals Beginner

What are callbacks in JavaScript?

A callback is a function passed into another function so it can be called later. Callbacks are used in event handlers, array methods, timers, and older asynchronous APIs. The main risk is losing clear control flow or error handling when callbacks become deeply nested or when this is not preserved.

Review callbacks →
Fundamentals Beginner

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

== checks equality after JavaScript converts one or both operands to compatible types. === checks equality without type conversion, so both the value and the type must already match. This makes === the safer default because expressions like false == 0 and "" == 0 can be true even though the original values mean different things.

Review equality rules →
Fundamentals Beginner

What is hoisting in JavaScript?

Hoisting is JavaScript behavior where declarations are registered before the surrounding code executes. Function declarations are initialized early enough to be called before their written position, while var declarations exist early but hold undefined until assignment. let and const bindings also exist before execution reaches them, but reading them too early throws because they are in the temporal dead zone.

Practice hoisting →
Fundamentals Intermediate

How do closures work in JavaScript?

A closure is formed when a function keeps access to variables from the scope where it was created. Those variables stay available even after the outer function has finished running. Closures are useful for callbacks, function factories, private state, and delayed work, but they can also keep memory alive longer than expected when references are retained.

Review closures →
Fundamentals Intermediate

What is the difference between arrow functions and regular functions?

Arrow functions do not create their own this, arguments object, or constructor behavior. They read this from the surrounding lexical scope, which makes them useful for callbacks that should preserve outer context. Regular functions are better for object methods, constructors, generators, and APIs where this should depend on how the function is called.

Compare function styles →
Fundamentals Intermediate

How does this work in JavaScript?

In a regular function, this is determined by how the function is called. In obj.method(), this is obj, but assigning the method to another variable and calling it can remove that receiver. bind, call, and apply set this explicitly, while arrow functions inherit this from the surrounding scope.

Review this binding →
Fundamentals Beginner

What is the difference between var, let, and const?

var is scoped to the nearest function and can be redeclared in the same scope. let and const are scoped to the nearest block, which makes them safer inside loops and conditionals. const requires an initial value and prevents rebinding, but object properties and array items can still be mutated.

Review variable scope →
Fundamentals Beginner

What is the difference between null, undefined, and undeclared?

undefined is the default value for a declared variable or missing object property that has no assigned value. null is an explicit value that represents an intentional absence. Undeclared means the identifier was never declared, so reading it directly throws a ReferenceError unless you check it with typeof.

Compare null and undefined →
Async Intermediate

What is the JavaScript event loop?

The event loop is the mechanism that lets JavaScript run synchronous code and later resume asynchronous callbacks. The call stack runs first, then queued microtasks run, then the runtime can take another task such as a timer or user event. This model allows a single JavaScript thread to coordinate timers, Promises, network callbacks, rendering, and user input.

Review the event loop →
Async Advanced

What are microtasks and macrotasks?

Microtasks are high-priority queued callbacks such as Promise.then, Promise.catch, Promise.finally, and queueMicrotask. Macrotasks are broader event-loop tasks such as timers, message events, and user input callbacks. After the current stack finishes, JavaScript drains the microtask queue before it moves to the next macrotask, so Promise callbacks usually run before setTimeout callbacks.

Compare task queues →
Async Beginner

What is the purpose of Promises?

A Promise is an object that represents the eventual result of asynchronous work. It starts pending, then either fulfills with a value or rejects with a reason. Promises make async code easier to compose because success, failure, chaining, and fan-out behavior all use the same contract.

Review Promise fundamentals →
Async Intermediate

How is async/await different from Promises?

async/await is syntax built on top of Promises, not a separate async system. An async function always returns a Promise, and await unwraps a fulfilled Promise or throws the rejection. It reads well for sequential steps, but independent work should still be started before awaiting or grouped with Promise.all.

Practice async/await →
Async Intermediate

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

Promise.all waits for every input to fulfill, but rejects immediately when one input rejects. Promise.allSettled waits for every input and returns status objects for both fulfilled and rejected results. Promise.race mirrors the first settled input, while Promise.any returns the first fulfillment and rejects only when every input rejects.

Compare Promise combinators →
Async Advanced

How do you handle async race conditions?

An async race condition happens when two or more async operations can finish in an order that no longer matches the current user intent. The usual fix is to cancel stale work with AbortController or ignore stale results with a request id, timestamp, or version token. The state update should happen only if the completed operation still matches the latest accepted operation.

Review async races →
Async Advanced

How do you debug async JavaScript issues?

Debug async issues by tracing when each operation starts, settles, updates state, and cleans up. Browser network tools show request timing, async stack traces show where callbacks came from, and rejected Promise handling shows hidden failure paths. A small reproduction helps separate stale responses, duplicate requests, missing cleanup, and swallowed errors.

Debug an async race →
Coding Beginner

What is the difference between map, filter, and reduce?

map transforms every item and returns a new array with the same length. filter keeps only the items that pass a condition and can return a shorter array. reduce accumulates the array into one result, such as a number, object, grouped map, or rebuilt array.

Compare array methods →
Coding Beginner

How do you remove duplicates from an array?

For primitive values, [...new Set(arr)] returns a new array with duplicates removed in first-seen order. Set uses SameValueZero equality, so NaN matches NaN and 1 is different from "1". For arrays of objects, deduplicate by a stable key such as id, because two object literals with the same fields are still different references.

Practice remove duplicates →
Coding Intermediate

How do you implement debounce?

Debounce creates a wrapper that waits until calls stop for a specified delay before running the original function. Each call clears the old timer and schedules a new one, so only the final call in a burst normally runs. The wrapper should pass through the latest arguments and this value, and optional cancel or flush methods can make it easier to control.

Practice debounce →
Coding Intermediate

How do you implement throttle?

Throttle creates a wrapper that runs the original function at most once during a fixed time window. Calls that happen during the cooldown can be ignored or saved for one trailing execution, depending on the chosen API. The implementation should preserve this, forward arguments, and define whether the first call, last call, or both can run.

Practice throttle →
Coding Intermediate

What is the difference between shallow and deep cloning?

A shallow clone copies only the top-level object or array and reuses nested object references. A deep clone recursively creates new nested objects and arrays so changes in the copy do not affect the original. Deep cloning is harder because real values can include cycles, Dates, Maps, Sets, class instances, functions, and prototypes.

Compare clone depth →
Coding Beginner

Why does Array.sort() sometimes sort numbers incorrectly?

Array.sort() sorts values as strings by default, not as numbers. That means [2, 10] can become [10, 2] because "10" comes before "2" lexicographically. Use a numeric comparator such as (a, b) => a - b, and copy the array first if the original order must be preserved.

Practice numeric sort →
Coding Intermediate

Why is immutability important in JavaScript interviews?

Immutability means representing a change by creating a new value instead of modifying the existing one. It prevents accidental updates through shared references, which is especially important for nested objects and arrays. It also makes UI rendering, reducer logic, memoization, undo history, and debugging easier because each state transition has a clear before and after.

Review immutability →
Browser + security Advanced

How do you prevent XSS in JavaScript?

Prevent XSS by treating user-controlled strings as unsafe until they are encoded, validated, or sanitized for the exact context where they are used. Prefer safe DOM APIs such as textContent for text, validate URLs before assigning href, and avoid dangerous sinks such as innerHTML for untrusted input. If trusted HTML rendering is required, use a proven sanitizer and add defenses such as Content Security Policy and Trusted Types.

Review DOM XSS prevention →
Fundamentals Intermediate

What is prototypal inheritance in JavaScript?

Prototypal inheritance means objects can delegate property lookups to another object through their prototype chain. If a property is not found on the object itself, JavaScript checks its prototype, then the next prototype, until it reaches null. Constructor functions and classes both use this prototype mechanism under the hood.

Review prototypes →
Fundamentals Intermediate

What is type coercion in JavaScript?

Type coercion is JavaScript converting a value from one type to another during an operation. It happens with loose equality, arithmetic, string concatenation, Boolean contexts, and many built-in APIs. Coercion can be useful, but explicit conversion with Number, String, or Boolean is clearer when behavior matters.

Review type coercion →

Code output

Output-based JavaScript interview questions

Practice the runtime details that usually decide JavaScript output questions: coercion, references, task queues, sort behavior, and this binding.

Beginner

What does typeof null return?

console.log(typeof null);
Output
"object"

typeof null returns "object" because of a long-standing JavaScript legacy bug. The value is still the primitive null, so check null directly with value === null.

Beginner

What is the output of loose equality compared with strict equality?

console.log(false == 0);
console.log(false === 0);
console.log("" == 0);
Output
true
false
true

Loose equality converts types before comparison, while strict equality does not. This is why strict equality is the default choice when the original value type matters.

Review equality rules →
Beginner

What is the output of Array.sort() without a comparator?

console.log([2, 10, 1].sort());
Output
[1, 10, 2]

sort() converts values to strings by default and compares them lexicographically. Use (a, b) => a - b for numeric sorting and copy first when mutation is not allowed.

Practice numeric sort →
Intermediate

What does this var loop log?

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

var creates one function-scoped binding shared by every callback. By the time the timers run, the loop has finished and that shared i is 3.

Review var and let →
Beginner

What happens when two variables reference the same object?

const a = { user: { name: "Ada" } };
const b = a;
b.user.name = "Lin";
console.log(a.user.name);
Output
"Lin"

Objects are assigned by reference, so a and b point at the same object. Mutating nested data through b is visible through a.

Review mutation →
Beginner

Why do string plus and minus behave differently?

console.log("5" + 1);
console.log("5" - 1);
Output
"51"
4

The + operator performs string concatenation when one side is a string. The - operator only has numeric meaning, so JavaScript coerces "5" to 5.

Review coercion →
Intermediate

What is the event loop output order?

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

Synchronous code runs first, then the microtask from Promise.then, then the timer task. This order is the key event-loop rule behind many async output questions.

Review event loop →
Intermediate

What happens when a method loses its receiver?

"use strict";
const user = {
  name: "Ada",
  getName() {
    return this.name;
  },
};
const fn = user.getName;
console.log(fn());
Output
TypeError

Calling fn() without user as the receiver makes this undefined in strict mode. Keep the receiver with user.getName(), bind the method, or wrap the call in another function.

Debug lost this →

Browser + DOM

DOM, browser, and security questions

Review browser-side JavaScript topics that commonly appear in frontend rounds: event phases, storage, safe DOM writes, URL handling, traversal, and cleanup.

Intermediate

What is event delegation?

Event delegation attaches one listener to a common parent and handles events from matching child elements. It works because many DOM events bubble upward. It reduces listener count for dynamic lists, but the handler still needs a reliable target check such as closest().

Review event delegation →
Intermediate

What is the difference between event bubbling and capturing?

Capturing runs listeners from the document down toward the target before the target phase. Bubbling runs listeners from the target back up toward the document. Most app code relies on bubbling, while capture is useful when a parent must observe an event before child handlers run.

Compare event phases →
Beginner

What is the difference between preventDefault() and stopPropagation()?

preventDefault() cancels the browser default action, such as navigating a link or submitting a form. stopPropagation() stops the event from continuing through the capture or bubble path. They solve different problems, so using one does not imply the other.

Beginner

What is the difference between innerHTML and textContent?

textContent writes text and treats characters such as < and > as text. innerHTML parses a string as HTML and can execute dangerous markup paths if the content is not trusted. Use textContent for user-controlled strings and only render sanitized HTML when markup is required.

Review safe DOM sinks →
Beginner

What is the difference between cookies, localStorage, and sessionStorage?

Cookies can be sent with HTTP requests and can use security flags such as HttpOnly, Secure, and SameSite. localStorage persists until cleared, while sessionStorage lasts for the current tab session. Storage APIs are convenient for non-sensitive client state, but they are readable by JavaScript.

Compare browser storage →
Advanced

How do you safely use user input in DOM URLs or HTML?

Treat user input as unsafe until it is encoded, validated, or sanitized for the exact context. For links, allow only safe schemes such as http, https, mailto, tel, or safe relative URLs. For HTML, use a reviewed sanitizer and avoid assigning untrusted strings to dangerous sinks.

Review DOM XSS prevention →
Intermediate

How do you search or traverse DOM nodes safely?

Use focused DOM APIs such as querySelector, querySelectorAll, closest, matches, and tree traversal instead of assuming a fixed child index. Code should handle missing nodes with null checks. Traversal logic also needs to preserve document order when the result order matters.

Practice DOM search →
Advanced

What causes browser memory leaks in JavaScript?

Leaks often come from event listeners, timers, subscriptions, detached DOM references, and unbounded Maps or caches that keep objects reachable. Cleanup should remove listeners, clear timers, abort stale work, and bound long-lived storage. DevTools memory snapshots help confirm whether objects are still retained after a user flow ends.

Practice bounded storage →

Most crucial JavaScript coding interview questions

Ranked by interview importance so you can start with the highest-signal implementation drills.

View full coding list

Need more implementation reps? Open the full coding list or follow a study plan.

Most crucial JavaScript concept questions for interviews

Ranked by interview importance to strengthen your explanation speed where it matters most.

View full concepts list

Need more concept coverage? Open the full concepts list or browse company packs.

JavaScript coverage map

JavaScript interview topic map

Use these JavaScript interview questions to connect cloning, promises, async races, immutability, sorting, security, debugging, and interview best practices with the deeper practice routes behind them.

Shallow vs deep cloning

A shallow clone copies the top-level array or object but keeps nested references shared. A deep clone copies nested structures too, which means you must discuss cycles, Dates, Maps, Sets, functions, prototypes, and performance before choosing an approach.

Compare shallow and deep copy →

Promises and async operations

Promises represent a future success or failure value and give async work a composable contract. Chaining, microtask timing, error propagation, async/await readability, and Promise combinators all follow from that same contract.

Review Promises and async/await →

Async race conditions and stale updates

Race conditions happen when multiple async operations can finish in a different order than user intent. Debug by naming the owner of the latest request, cancelling or ignoring stale work, and testing success, error, abort, and retry paths.

Explain async race conditions →

Immutability and state updates

Immutability keeps state transitions traceable, avoids accidental shared-reference bugs, and makes UI change detection easier to reason about. Copy caller-owned or shared data, and keep mutation limited to local implementation details.

Review mutability vs immutability →

Sorting, comparators, and mutation

JavaScript sort converts values to strings unless you pass a comparator, so numeric sorting needs a function such as a - b. Also call out that sort mutates the array unless you copy first.

Practice numeric sorting →

DOM XSS prevention

XSS answers should separate escaping text from sanitizing HTML. Prefer safe DOM APIs such as textContent, validate URLs before assigning href, avoid dangerous sinks, and use Trusted Types or reviewed sanitizers when HTML is unavoidable.

Review DOM XSS prevention →

Common mistakes in JavaScript interviews

  • Mutating inputs without saying soArray.sort, push, splice, and nested object edits can change caller-owned data. Copy first when the contract expects immutability.
  • Sorting numbers lexicographicallyDefault sort compares strings, so 100 can come before 20. Use an explicit comparator and mention mutation.
  • Dropping Promise returns or rejection handlingA missing return breaks chains, and unhandled rejections hide failure states. Explain success, error, and cleanup paths.
  • Explaining closures as copied valuesClosures keep access to lexical bindings. That distinction matters for loops, delayed callbacks, and stale-state bugs.
  • Using JSON clone as a universal deep cloneJSON cloning drops undefined, functions, Symbols, prototypes, Dates, Maps, Sets, BigInt, and cycles. Name the trade-off before using it.
  • Fixing XSS with partial string filtersBlocklists miss dangerous contexts. Choose safe sinks, encode for the right context, sanitize reviewed HTML, and validate URLs.

JavaScript coding interview best practices

  • Restate inputs, outputs, constraints, mutation policy, and edge cases before writing code.
  • Prefer the simplest correct implementation first, then explain the built-in or optimized variant as a follow-up.
  • Test empty input, single item, duplicates, nested data, invalid values, async rejection, cancellation, and ordering.
  • Narrate trade-offs clearly: mutation versus copying, shallow versus deep behavior, sync versus async control flow, and readability versus performance.
  • Finish by naming complexity, failure modes, and the regression tests you would keep.
Open the JavaScript prep path →

How to debug async JavaScript issues

  • Trace ownership firstIdentify which request, timer, listener, or callback owns the next state update before changing code.
  • Separate ordering from failureCheck whether the bug is stale success, late rejection, missing cleanup, duplicate work, or a swallowed error.
  • Use browser tools deliberatelyPause on exceptions, inspect async stack traces, watch network cancellation, and add focused logs around start, settle, and cleanup.
  • Protect the regressionKeep tests for overlapping requests, rejected promises, aborts, retries, and component or listener teardown when those behaviors exist.
Practice an async race debug prompt →

Best resources for JavaScript interview preparation

Use official references for language behavior and security, then practice the same ideas through interview prompts.

Interview prep context

What JavaScript interview rounds test

JavaScript interviews usually test execution order, data transformation, async safety, and whether you can explain trade-offs while coding.

Editorial policy

What this round tests

  • Async behavior, closures, prototypes, arrays, maps, and utility implementation details.
  • Debugging stale state, race conditions, equality, coercion, and edge cases.
  • Clear narration: what you chose, what can break, and how you would test it.

How to use these questions

  • Start with one coding prompt, then answer one concept question out loud.
  • Use the prep path when misses repeat around async, closures, or utility design.
  • Return to this hub to pick the next small rep instead of browsing the full library.

This hub is assembled from high-priority FrontendAtlas JavaScript prompts and reviewed for interview-specific trade-off language.

Quick answers

Common questions before you start

Are these JavaScript interview questions for beginners or experienced developers?

Yes. The short-answer grid starts with beginner fundamentals, then moves into intermediate and advanced topics such as async races, prototypes, browser events, XSS, and debugging.

Do these include output-based JavaScript interview questions?

Yes. The output section includes code snippets for coercion, sort behavior, object references, var timing, microtasks, timers, and this binding so you can practice predicting console output.

Where should I practice JavaScript coding interview questions?

Start with the coding prompts on this page, then open the full JavaScript coding list for utilities such as sort, debounce, throttle, duplicate removal, cloning, and DOM traversal.

What are common mistakes in JavaScript interviews?

Common misses include mutating inputs, sorting numbers without a comparator, losing this in callbacks, treating closures as frozen snapshots, ignoring rejected promises, and using JSON cloning as a universal deep-copy answer.

What are the best resources for JavaScript interview preparation?

Use MDN for practical language reference, the ECMAScript specification for precise semantics, Chrome DevTools docs for debugging workflow, OWASP guidance for XSS prevention, and FrontendAtlas practice routes for interview drills.

Keep the scope tight

Start with one route first. Then expand into Question Library, Study Plans, and Company Prep only when you need them.

Recommended preparation

Recommended JavaScript interview preparation

Start with the interview preparation guide and shared baseline, then tighten JavaScript coding, concepts, and follow-up depth.

  1. Frontend interview preparation guideStart hereLearn the interview stages and scoring signals before narrowing into this technology.Process, rounds, and plan
  2. FrontendAtlas Essential 60Start with the shared shortlist to stabilize interview fundamentals before framework-specific depth.Shared frontend baseline
  3. JavaScript coding + concept questionsPractice JavaScript implementation prompts and explanation follow-ups from one filtered library view.Coding execution + concept recall
  4. JavaScript interview prep pathA 7/14/30-day path for async, closures, state, and utility prompts.Framework-specific sequencing
  5. Final-round coverageAdd system design, behavioral, and company-style follow-ups after the framework baseline is stable.System design, behavioral, company rounds