Technology

JavaScript Interview Questions and Answers

JavaScript is asked in almost every frontend, full-stack and Node.js interview. These JavaScript interview questions start with data types, scope and functions for freshers, then cover closures, this, prototypes, promises, async/await, the event loop and performance for experienced developers.

30 questions · Updated

Reading answers is not the same as saying them.Practise JavaScript questions out loud and get a score, what you missed and a model answer for each one.
Practise free with AI
JavaScript Interview Questions with answers. Examples: What are the data types in JavaScript? What is the difference between null and undefined? What is hoisting? How does the this keyword work?
JavaScript Interview Questions: 30 questions with model answers on this page.

Basic JavaScript interview questions

Fundamentals, definitions and simple scenarios. Good for freshers and warm-ups.

1. What are the data types in JavaScript?

Answer flow · 3 steps
  1. There are seven primitive types: string, number, bigint, boolean, undefined, null and symbol.

  2. Everything else is an object, including arrays, functions and dates.

  3. Primitives are immutable and compared by value, while objects are compared by reference, so two different objects with the same contents are not equal. typeof null returning "object" is a well-known historical bug.

2. What is the difference between null and undefined?

undefined means a variable has been declared but not assigned, a missing function argument, or a property that does not exist. null is an intentional "no value" set by the developer. null == undefined is true, but null === undefined is false. The ?? operator treats both as missing values.

3. What is hoisting?

Hoisting means declarations are processed before code runs. Function declarations are fully hoisted, so they can be called before they appear. var declarations are hoisted and initialised to undefined. let, const and class declarations are hoisted but stay in the temporal dead zone until their line runs, so accessing them earlier throws a ReferenceError.

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

var is scoped to the function, is hoisted with the value undefined and can be declared twice. let and const are scoped to the nearest block, such as an if or a loop, and cannot be used before their declaration line. const must be assigned once and cannot be reassigned, although the object or array it holds can still be changed. Modern code uses const by default and let when a value must change.

5. Why should you use === instead of ==?

== converts the two values to the same type before comparing, which gives surprising results: "0" == 0 and "" == 0 are true, and [] == false is true. === compares both type and value with no conversion, so it behaves predictably. A common, deliberate exception is x == null, which is true for both null and undefined.

6. What types of scope does JavaScript have?

Answer flow · 5 steps
  1. Global scope is available everywhere.

  2. Function scope belongs to variables declared inside a function.

  3. Block scope, created by let and const inside curly braces, limits a variable to that block.

  4. Module scope means top-level variables in an ES module are private to that file unless exported.

  5. JavaScript uses lexical scope: a function can read variables from where it was written, not from where it is called.

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

Answer flow · 4 steps
  1. Both use three dots.

  2. Spread expands an array or object into individual items, for example copying [...arr], merging {...a, ...b} or passing an array as arguments with Math.max(...nums).

  3. Rest does the opposite and collects several items into one array or object, for example function sum(...nums) or const { id, ...rest } = user.

  4. The position decides which one it is.

8. Which values are falsy in JavaScript?

Answer flow · 3 steps
  1. false, 0, -0, 0n (BigInt zero), "" (empty string), null, undefined and NaN.

  2. Everything else is truthy, including "0", "false", empty arrays [] and empty objects {}.

  3. This matters in conditions such as if (items.length), and is why ?? is often better than || for defaults, since || also replaces valid values like 0 and "".

9. What is the difference between typeof and instanceof?

Answer flow · 3 steps
  1. typeof returns a string with the basic type of a value: "string", "number", "boolean", "undefined", "object", "function", "symbol" or "bigint".

  2. It cannot tell arrays from objects and returns "object" for null. instanceof checks whether an object has a constructor's prototype in its prototype chain, for example date instanceof Date.

  3. To check for an array, use Array.isArray().

10. Which array methods change the original array?

push, pop, shift, unshift, splice, sort, reverse and fill all change the array in place. slice, concat, map, filter, reduce, and the newer toSorted, toReversed, toSpliced and with return new arrays and leave the original untouched. In React and other state-based code, the non-mutating methods are preferred so changes can be detected.

11. What is NaN, and how do you check for it?

Answer flow · 4 steps
  1. NaN means "Not a Number" and is the result of invalid maths, such as Number("abc") or 0 / 0.

  2. Its type is still "number".

  3. NaN is the only value not equal to itself, so NaN === NaN is false.

  4. Use Number.isNaN(value) to check for it; the older global isNaN converts its argument first, so isNaN("abc") is true, which is misleading.

Intermediate JavaScript interview questions

Applied problems, trade-offs and questions about your own projects.

12. How does the this keyword work?

Answer flow · 5 steps
  1. this depends on how a function is called.

  2. In a method call obj.fn(), this is obj.

  3. In a plain function call it is undefined in strict mode (or the global object otherwise).

  4. With new it is the new object. call, apply and bind set it explicitly.

  5. Arrow functions do not have their own this; they use this from the surrounding scope, which is why they are handy in callbacks.

13. What is prototypal inheritance?

Answer flow · 4 steps
  1. Every object has an internal link to a prototype object.

  2. When a property is not found on the object, JavaScript looks up the prototype chain until it finds it or reaches null.

  3. Classes are syntax on top of this: methods defined in a class live on its prototype and are shared by all instances.

  4. Object.create(proto) creates an object with a given prototype.

14. What are promises, and how does async/await relate to them?

Answer flow · 3 steps
  1. A promise represents a value that will be available later, in a pending, fulfilled or rejected state, with .then, .catch and .finally to handle the result. async functions always return a promise, and await pauses the function until a promise settles, so asynchronous code reads like synchronous code.

  2. Errors are handled with try/catch.

  3. Promise.all runs tasks in parallel and fails fast; Promise.allSettled waits for all.

15. What is the difference between map, filter, reduce and forEach?

map returns a new array with each element transformed. filter returns a new array with elements that pass a test. reduce combines all elements into a single value, such as a total or an object grouped by key. forEach runs a function for each element and returns undefined, used only for side effects. map, filter and reduce do not change the original array.

16. What is a closure? Give an example.

Answer flow · 3 steps
  1. A closure is a function bundled with the variables of the scope it was created in.

  2. The function keeps access to those variables even after the outer function has returned.

  3. Closures make private state possible, and they power callbacks, memoisation, debounce functions and React hooks.

function makeCounter() {
  let count = 0; // private to the closure
  return () => ++count;
}
const next = makeCounter();
next(); // 1
next(); // 2

17. Predict the output: setTimeout, a promise and console.log.

Answer flow · 4 steps
  1. Synchronous code runs first, then all microtasks (promise callbacks), then macrotasks (timers).

  2. So this prints 1, 4, 3, 2.

  3. Even a 0 ms timeout waits until the call stack and the microtask queue are empty.

  4. This question tests whether you understand the event loop.

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

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

All three set the value of this for a function. call invokes it immediately with arguments listed one by one, fn.call(obj, a, b). apply invokes it immediately with arguments as an array, fn.apply(obj, [a, b]). bind does not call the function; it returns a new function with this (and optionally some arguments) fixed, which is useful for callbacks and event handlers.

19. What is currying?

Answer flow · 3 steps
  1. Currying turns a function that takes several arguments into a chain of functions that each take one, so add(a, b) becomes add(a)(b).

  2. It lets you create specialised functions by fixing some arguments, such as const addTax = multiply(1.18), and is common in functional programming and utility libraries.

  3. It relies on closures to remember earlier arguments.

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

Answer flow · 3 steps
  1. ES modules use import and export, are the official JavaScript standard, work in browsers and Node.js, load asynchronously, are statically analysable so bundlers can tree-shake unused code, and support top-level await.

  2. CommonJS uses require and module.exports, loads synchronously and was Node.js's original system.

  3. New code should use ES modules.

21. When would you use Map and Set instead of objects and arrays?

Answer flow · 3 steps
  1. A Map is a key-value collection where keys can be any type, including objects, keeps insertion order, has a size property and is faster for frequent additions and removals.

  2. Plain objects are better for fixed records and JSON.

  3. A Set stores unique values, which makes removing duplicates easy with [...new Set(arr)] and membership checks with has() faster than array.includes on large data.

22. What are generators and iterators?

Answer flow · 3 steps
  1. An iterator is an object with a next() method that returns { value, done }.

  2. Anything with a [Symbol.iterator] method is iterable and works with for...of and spread.

  3. A generator function, written function*, returns an iterator and uses yield to pause and produce values one at a time, which suits lazy sequences, infinite streams and custom iteration over data structures.

High level JavaScript interview questions

System design, deep internals, leadership and tough follow-ups.

23. Explain debouncing and throttling.

Answer flow · 3 steps
  1. Debouncing delays a function until a certain time has passed since the last call, so it runs once after the user stops, which suits search inputs and resize handlers.

  2. Throttling makes a function run at most once per interval no matter how often it is triggered, which suits scroll and mousemove handlers.

  3. Both are built with closures around setTimeout and reduce unnecessary work and API calls.

24. What causes memory leaks in JavaScript, and how do you find them?

Answer flow · 3 steps
  1. Common causes are forgotten timers and intervals, event listeners that are never removed, closures holding large objects, detached DOM nodes still referenced in code, and caches that grow forever.

  2. I find them with Chrome DevTools: take heap snapshots before and after an action, compare them, and look for objects that keep growing.

  3. Cleaning up in component unmount and using WeakMap for caches helps.

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

Answer flow · 3 steps
  1. A shallow copy, made with the spread operator, Object.assign or Array.slice, copies only the top level; nested objects are still shared, so changing them affects the original.

  2. A deep copy duplicates every level. structuredClone() is the modern built-in way to deep copy and handles dates, maps and circular references.

  3. JSON.parse(JSON.stringify(obj)) works for plain data but loses functions, dates and undefined.

26. What are WeakMap and WeakSet used for?

Answer flow · 3 steps
  1. WeakMap and WeakSet hold their object keys weakly: if nothing else references the object, it can be garbage collected and its entry disappears.

  2. They are not iterable and have no size.

  3. They are used to attach private data or metadata to objects, such as DOM nodes, or to cache results per object without causing memory leaks.

27. What are Proxy and Reflect?

Answer flow · 3 steps
  1. A Proxy wraps an object and intercepts operations on it, such as reading, writing or deleting properties, through handler functions called traps.

  2. It is used for validation, logging, default values and reactivity systems such as Vue 3's.

  3. Reflect provides methods matching each trap, such as Reflect.get and Reflect.set, so a trap can perform the default behaviour after its own logic.

28. How does garbage collection work in JavaScript?

Answer flow · 4 steps
  1. JavaScript engines free memory automatically using reachability.

  2. Starting from roots such as global variables and the current call stack, the collector marks every object it can reach and sweeps away the rest (mark and sweep).

  3. V8 uses generations: new objects are collected often and quickly, and survivors move to an old space collected less often.

  4. Leaks happen when unwanted objects stay reachable.

29. What does strict mode do?

Answer flow · 3 steps
  1. Strict mode, turned on with "use strict" and automatically in ES modules and classes, makes JavaScript safer.

  2. Assigning to an undeclared variable throws an error instead of creating a global, this is undefined in plain function calls instead of the global object, duplicate parameter names are not allowed, and writing to read-only properties throws.

  3. It catches bugs early.

30. How does JavaScript run in the engine?

Answer flow · 3 steps
  1. An engine such as V8 parses source code into an abstract syntax tree, an interpreter (Ignition) turns it into bytecode and runs it quickly, and an optimising compiler (TurboFan) compiles frequently used functions into fast machine code based on the types it has observed.

  2. If those assumptions break, for example a function suddenly receives different types, the code is de-optimised.

  3. Consistent object shapes and types help performance.

JavaScript machine coding round questions

Tasks you build live in 30 to 60 minutes. What interviewers look for, plus a compact solution to compare with yours.

Write a polyfill for Function.prototype.bind.

Tests this, closures and apply. The returned function must keep the bound this and any preset arguments, and accept more arguments when called.

Function.prototype.myBind = function (context, ...preset) {
  const fn = this;
  return function (...later) {
    return fn.apply(context, [...preset, ...later]);
  };
};

const greet = function (greeting) { return greeting + ', ' + this.name; };
greet.myBind({ name: 'Asha' })('Hello'); // "Hello, Asha"

Implement a memoize function.

Answer flow · 3 steps
  1. Checks closures and caching.

  2. Use a Map keyed by the arguments.

  3. Discuss limits: JSON.stringify keys only suit simple arguments, and the cache can grow without bound.

function memoize(fn) {
  const cache = new Map();
  return function (...args) {
    const key = JSON.stringify(args);
    if (!cache.has(key)) cache.set(key, fn.apply(this, args));
    return cache.get(key);
  };
}

const slowSquare = (n) => n * n;
const fastSquare = memoize(slowSquare);

Write a polyfill for Array.prototype.map.

A common warm-up. Call the callback with the element, index and array, skip empty slots, and return a new array without changing the original.

Array.prototype.myMap = function (callback, thisArg) {
  const result = new Array(this.length);
  for (let i = 0; i < this.length; i++) {
    if (i in this) result[i] = callback.call(thisArg, this[i], i, this);
  }
  return result;
};

[1, 2, 3].myMap((x) => x * 2); // [2, 4, 6]
Ready to test yourself?Pick your topics and level, answer by voice or text, and get instant feedback. Free.
Start a mock interview

Preparing for a frontend developer interview?

See all Frontend Developer interview questions, covering HTML, CSS, JavaScript, TypeScript, React and more.

Related skill interview questions

More technology interview questions

HR round, company and bank interview questions

Bank and government exams

Interview questions for other fields