100+ JavaScript Interview Questions & Answers

JavaScript Interview Questions

Fundamentals & Data Types

  • 1. What is JavaScript?

    JavaScript is a high-level, interpreted, single-threaded programming language primarily used to make web pages interactive. It supports object-oriented, functional, and event-driven programming paradigms and runs in browsers and on servers (via Node.js).

  • 2. What are the primitive data types in JavaScript?

    There are seven: string, number, boolean, null, undefined, symbol, and bigint. Everything else is an object.

  • 3. What is the difference between null and undefined?

    undefined means a variable has been declared but not assigned a value. null is an intentional assignment representing "no value." typeof undefined is "undefined", while typeof null is "object" (a historical bug).

  • 4. What is the difference between == and ===?

    == compares values after type coercion (loose equality), while === compares both value and type (strict equality). Always prefer === to avoid unexpected coercion.

  • 5. What is typeof and give examples.

    `typeof` returns a string indicating the operand's type. E.g. `typeof 1` → `"number"`, `typeof "a"` → `"string"`, `typeof []` → `"object"`, `typeof function(){}` → `"function"`.

  • 6. What is the difference between `var`, `let`, and `const`?

    `var` is function-scoped and hoisted (initialized as `undefined`). `let` and `const` are block-scoped and hoisted but not initialized (temporal dead zone). `const` cannot be reassigned, though object contents can still mutate.

  • 7. What is hoisting?

    Hoisting is JavaScript's behavior of moving declarations to the top of their scope during compilation. `var` and function declarations are hoisted and initialized; `let`/`const` are hoisted but remain in the temporal dead zone until declared.

  • 8. What is the Temporal Dead Zone (TDZ)?

    The TDZ is the period between entering a scope and the actual declaration of a `let`/`const` variable, during which accessing the variable throws a `ReferenceError`.

  • 9. What are truthy and falsy values?

    Falsy values are `false`, `0`, `-0`, `0n`, `""`, `null`, `undefined`, and `NaN`. Everything else is truthy, including `"0"`, `[]`, and `{}`.

  • 10. What is `NaN` and how do you check for it?

    `NaN` (Not a Number) is a special numeric value representing an invalid number. `NaN === NaN` is `false`, so use `Number.isNaN(value)` to check for it reliably.

  • 11. What is the difference between `Number.isNaN()` and global `isNaN()`?

    Global `isNaN()` coerces the argument to a number first (so `isNaN("abc")` is `true`). `Number.isNaN()` returns `true` only if the value is actually `NaN` without coercion.

  • 12. What is type coercion?

    Type coercion is the automatic conversion of values from one type to another, e.g. `"5" + 1` → `"51"` (number to string) and `"5" - 1` → `4` (string to number).

  • 13. Explain `parseInt` vs `Number`.

    `parseInt` parses a string up to the first invalid character (`parseInt("12px")` → `12`), while `Number("12px")` returns `NaN` because it requires the entire string to be a valid number.

  • 14. What is the difference between primitive and reference types?

    Primitives are stored and copied by value. Objects (arrays, functions, objects) are stored and copied by reference, so two variables can point to the same underlying object.

  • 15. How do you check if a value is an array?

    Use `Array.isArray(value)`, which reliably returns a boolean, rather than `typeof` which returns `"object"` for arrays.

Functions & Scope

  • 16. What is a closure?

    A closure is a function that retains access to variables from its lexical (outer) scope even after that outer function has returned. Closures enable data privacy and function factories.

  • 17. Give a practical use of closures.

    Creating private counters:

  • 18. What is the difference between function declarations and function expressions?

    Function declarations are hoisted entirely and can be called before they appear. Function expressions (assigned to variables) are not hoisted with their body and must be defined before use.

  • 19. What are arrow functions and how do they differ from regular functions?

    Arrow functions provide concise syntax and do not have their own `this`, `arguments`, `super`, or `prototype`. They inherit `this` lexically from the enclosing scope and cannot be used as constructors.

  • 20. What is the `this` keyword?

    `this` refers to the execution context of a function. Its value depends on how the function is called: the global object (or `undefined` in strict mode), the object before the dot, a bound value, or a new instance with `new`.

  • 21. What do `call`, `apply`, and `bind` do?

    All set `this` explicitly. `call` invokes immediately with comma-separated args, `apply` invokes immediately with an array of args, and `bind` returns a new function with `this` permanently bound.

  • 22. What is an IIFE?

    An Immediately Invoked Function Expression runs as soon as it is defined: `(function(){ /* ... */ })();`. It creates a private scope to avoid polluting the global namespace.

  • 23. What is currying?

    Currying transforms a function with multiple arguments into a sequence of functions each taking one argument: `add(1)(2)(3)`. It enables partial application and reuse.

  • 24. What are default parameters?

    Default parameters let you assign fallback values in the function signature: `function greet(name = "Guest") {}`. The default is used when the argument is `undefined`.

  • 25. What are rest parameters?

    Rest parameters collect remaining arguments into an array using `...`: `function sum(...nums) {}`. They must be the last parameter.

  • 26. What is the `arguments` object?

    `arguments` is an array-like object available inside regular (non-arrow) functions containing all passed arguments. Modern code prefers rest parameters instead.

  • 27. What is a higher-order function?

    A higher-order function takes one or more functions as arguments and/or returns a function. Examples include `map`, `filter`, `reduce`, and `setTimeout`.

  • 28. What is function composition?

    Function composition combines multiple functions so the output of one becomes the input of the next: `compose(f, g)(x)` equals `f(g(x))`.

  • 29. What is recursion?

    Recursion is when a function calls itself to solve a problem by breaking it into smaller subproblems, with a base case to stop the recursion. **30. What is the difference between parameters and arguments?** Parameters are the named variables in a function definition; arguments are the actual values passed when the function is called.

Objects & Prototypes

  • 31. What is prototypal inheritance?

    Objects in JavaScript inherit properties and methods from a prototype object via the prototype chain. When a property isn't found on an object, JS looks up its `[[Prototype]]` until it reaches `null`.

  • 32. What is the prototype chain?

    The prototype chain is the series of linked prototype objects JS traverses to resolve property lookups, ending at `Object.prototype` and then `null`.

  • 33. How do you create an object in JavaScript?

    Several ways: object literal `{}`, constructor function with `new`, `Object.create(proto)`, ES6 `class`, or `new Object()`.

  • 34. What is the difference between `Object.create()` and a constructor?

    `Object.create(proto)` creates a new object with the specified prototype directly. A constructor function paired with `new` creates an instance and links it to the constructor's `prototype` property.

  • 35. What are getters and setters?

    Getters and setters are special methods defined with `get`/`set` that let you run logic when reading or writing a property, while accessing it like a normal property.

  • 36. How do you clone an object?

    Shallow clone: `Object.assign({}, obj)` or `{...obj}`. Deep clone: `structuredClone(obj)` (modern) or `JSON.parse(JSON.stringify(obj))` (loses functions/dates).

  • 37. What is the difference between shallow and deep copy?

    A shallow copy duplicates only the top-level properties; nested objects still share references. A deep copy recursively duplicates all nested structures so nothing is shared.

  • 38. What does `Object.freeze()` do?

    `Object.freeze()` makes an object immutable—you cannot add, delete, or change its properties. It is shallow, so nested objects can still be mutated.

  • 39. What is the difference between `Object.keys`, `Object.values`, and `Object.entries`?

    `Object.keys` returns an array of property names, `Object.values` returns an array of values, and `Object.entries` returns an array of `[key, value]` pairs.

  • 40. What is the difference between `hasOwnProperty` and the `in` operator?

    `hasOwnProperty` checks only the object's own properties. The `in` operator checks own and inherited properties along the prototype chain.

  • 41. What are computed property names?

    Computed property names let you use an expression as a key in object literals using bracket syntax: `{ [key]: value }`.

  • 42. What is object destructuring?

    Destructuring extracts properties into variables: `const { name, age } = person;`. You can rename, set defaults, and destructure nested objects.

  • 43. What is the spread operator?

    The spread operator (`...`) expands iterables/objects into individual elements: merging arrays `[...a, ...b]`, cloning, or spreading object properties `{...obj}`.

  • 44. What are symbols and why use them?

    `Symbol` creates unique, immutable identifiers often used as object keys to avoid naming collisions and to define well-known behaviors (like `Symbol.iterator`).

  • 45. What is optional chaining?

    Optional chaining (`?.`) safely accesses nested properties, returning `undefined` instead of throwing if an intermediate value is `null`/`undefined`: `user?.address?.city`.

Arrays

  • 46. What is the difference between `map` and `forEach`?

    `map` returns a new array of transformed values, while `forEach` executes a callback for side effects and returns `undefined`. Use `map` when you need a result.

  • 47. What does `reduce` do?

    `reduce` accumulates array values into a single result using an accumulator and callback: `[1,2,3].reduce((acc, n) => acc + n, 0)` → `6`.

  • 48. What is the difference between `filter` and `find`?

    `filter` returns an array of all elements matching a condition; `find` returns only the first matching element (or `undefined`).

  • 49. What is the difference between `slice` and `splice`?

    `slice` returns a shallow copy of a portion without modifying the original. `splice` mutates the array by removing/adding elements in place.

  • 50. How do you remove duplicates from an array?

    Use a `Set`: `[...new Set(arr)]` removes duplicate primitive values concisely.

  • 51. What is the difference between `some` and `every`?

    `some` returns `true` if at least one element passes the test; `every` returns `true` only if all elements pass.

  • 52. How do you flatten a nested array?

    Use `arr.flat(depth)` for a specified depth, or `arr.flat(Infinity)` to fully flatten. `flatMap` maps and flattens one level.

  • 53. What is the difference between `push`/`pop` and `shift`/`unshift`?

    `push`/`pop` add/remove from the end of an array; `unshift`/`shift` add/remove from the beginning.

  • 54. How does `sort` work by default?

    By default `sort` converts elements to strings and sorts by Unicode order, which mis-sorts numbers. Provide a comparator: `arr.sort((a, b) => a - b)`.

  • 55. What is the difference between `indexOf` and `includes`?

    `indexOf` returns the index of an element (or `-1`), while `includes` returns a boolean. `includes` also correctly detects `NaN`.

  • 56. What does `Array.from` do?

    `Array.from` creates a new array from an iterable or array-like object, optionally applying a map function: `Array.from({length: 3}, (_, i) => i)` → `[0,1,2]`.

  • 57. What is the difference between `for...of` and `for...in`?

    `for...of` iterates over iterable values (arrays, strings, maps). `for...in` iterates over enumerable property keys, including inherited ones—best for objects.

  • 58. How do you find the largest number in an array?

    Use `Math.max(...arr)` with the spread operator, or `arr.reduce((a, b) => Math.max(a, b))`.

  • 59. What is array destructuring with default values?

    You can assign defaults during destructuring: `const [a = 1, b = 2] = [10];` gives `a = 10`, `b = 2`.

  • 60. What does `fill` do?

    `fill(value, start, end)` replaces array elements in place with a static value within the specified range.

Asynchronous JavaScript

  • 61. What is the event loop?

    The event loop is the mechanism that allows single-threaded JavaScript to handle async operations. It continuously checks the call stack and, when empty, moves queued callbacks (from task/microtask queues) onto the stack for execution.

  • 62. What is the difference between the microtask and macrotask queues?

    Microtasks (Promises, `queueMicrotask`, `MutationObserver`) run before macrotasks (`setTimeout`, `setInterval`, I/O). After each macrotask, all pending microtasks are drained.

  • 63. What is a callback function?

    A callback is a function passed as an argument to another function, executed later—commonly used for async operations and event handlers.

  • 64. What is callback hell?

    Callback hell is deeply nested callbacks that make code hard to read and maintain. It's typically solved with Promises or `async/await`.

  • 65. What is a Promise?

    A Promise represents the eventual result of an asynchronous operation, existing in one of three states: `pending`, `fulfilled`, or `rejected`. It has `.then`, `.catch`, and `.finally` methods.

  • 66. What is `async/await`?

    `async/await` is syntactic sugar over Promises. An `async` function returns a Promise, and `await` pauses execution until a Promise settles, letting you write async code that reads synchronously.

  • 67. How do you handle errors with `async/await`?

    Wrap `await` calls in a `try...catch` block, or attach `.catch()` to the returned Promise.

  • 68. What is the difference between `Promise.all` and `Promise.allSettled`?

    `Promise.all` rejects immediately if any promise rejects and resolves with all results otherwise. `Promise.allSettled` always resolves with an array describing each promise's outcome (fulfilled or rejected).

  • 69. What is `Promise.race`?

    `Promise.race` settles as soon as the first promise settles (resolve or reject), with that promise's value or reason.

  • 70. What is `Promise.any`?

    `Promise.any` resolves with the first fulfilled promise, ignoring rejections. It rejects with an `AggregateError` only if all promises reject.

  • 71. What is the difference between synchronous and asynchronous code?

    Synchronous code executes line by line, blocking until each operation completes. Asynchronous code allows operations to run in the background without blocking, using callbacks/promises to handle results later.

  • 72. What does `setTimeout(fn, 0)` do?

    It schedules `fn` to run as a macrotask after the current synchronous code and all microtasks complete—not immediately, despite the `0` delay.

  • 73. How do you make sequential vs parallel async calls?

    Sequential: `await` each call one after another. Parallel: start all promises first, then `await Promise.all([...])` to wait for them together.

  • 74. What is `fetch` and what does it return?

    `fetch` makes network requests and returns a Promise resolving to a `Response` object. You then call `.json()` or `.text()` (which also return Promises) to read the body.

  • 75. Why does `fetch` not reject on HTTP error status?

    `fetch` only rejects on network failures. HTTP errors like 404 or 500 still resolve, so you must check `response.ok` manually.

ES6+ & Modern Features

  • 76. What are template literals?

    Template literals use backticks and allow embedded expressions with `${}` and multi-line strings: ``Hello, ${name}!``.

  • 77. What is the nullish coalescing operator?

    `??` returns the right operand only when the left is `null` or `undefined` (unlike `||`, which also triggers on falsy values like `0` or `""`).

  • 78. What are ES modules?

    ES modules use `import`/`export` to share code between files, with static analysis, strict mode by default, and support for tree-shaking.

  • 79. What is the difference between named and default exports?

    Named exports export multiple bindings by name and must be imported with matching names (or aliased). A default export is a single value imported with any name.

  • 80. What are generators?

    Generators are functions declared with `function*` that can pause and resume using `yield`, returning an iterator. They're useful for lazy evaluation and custom iteration.

  • 81. What is an iterator?

    An iterator is an object with a `next()` method returning `{ value, done }`. Objects implementing `Symbol.iterator` are iterable and work with `for...of`.

  • 82. What is the difference between `Map` and a plain object?

    `Map` allows any type as keys (including objects), maintains insertion order, has a `size` property, and is optimized for frequent additions/removals. Objects only allow string/symbol keys.

  • 83. What is a `Set`?

    A `Set` is a collection of unique values of any type, with methods like `add`, `has`, `delete`, and a `size` property.

  • 84. What are `WeakMap` and `WeakSet`?

    `WeakMap`/`WeakSet` hold weak references to objects, allowing garbage collection when there are no other references. They are not iterable and help prevent memory leaks.

  • 85. What is destructuring with function parameters?

    You can destructure objects/arrays directly in the parameter list: `function draw({ x = 0, y = 0 } = {}) {}`, providing named options with defaults.

  • 86. What are tagged template literals?

    A tagged template calls a function with the string parts and interpolated values, allowing custom string processing (used by libraries like styled-components and for i18n).

  • 87. What is the difference between `for await...of` and `for...of`?

    `for await...of` iterates over async iterables, awaiting each value—useful for streams and paginated async data. `for...of` handles synchronous iterables.

  • 88. What is `globalThis`?

    `globalThis` provides a standard way to access the global object across environments (`window` in browsers, `global` in Node.js, `self` in workers).

  • 89. What are private class fields?

    Private fields are declared with a `#` prefix and are only accessible within the class: `class C { #secret = 1; }`. Access outside throws a syntax error.

  • 90. What is the difference between static and instance methods?

    Static methods (declared with `static`) belong to the class itself and are called on the class. Instance methods belong to instances and require an object created with `new`.

Miscellaneous & Advanced

  • 91. What is event delegation?

    Event delegation attaches a single listener to a parent element and uses event bubbling to handle events from child elements, improving performance and handling dynamically added elements.

  • 92. What is the difference between event bubbling and capturing?

    Bubbling propagates events from the target element up to ancestors (default). Capturing propagates from the root down to the target. You opt into capturing with `addEventListener(type, fn, true)`.

  • 93. What is debouncing and throttling?

    Debouncing delays a function until a pause in events (e.g. after the user stops typing). Throttling limits a function to run at most once per interval. Both control high-frequency event handlers.

  • 94. What is memoization?

    Memoization caches the results of expensive function calls keyed by their arguments, returning the cached result on repeated calls with the same inputs.

  • 95. What is the difference between `slice` and `substring` for strings?

    Both extract substrings, but `slice` accepts negative indices (counting from the end) while `substring` treats negatives as `0` and swaps arguments if start > end.

  • 96. What is strict mode?

    Strict mode (`"use strict";`) enforces stricter parsing and error handling—preventing undeclared variables, disallowing duplicate params, and making `this` `undefined` in unbound functions.

  • 97. What is the difference between deep equality and reference equality?

    Reference equality (`===`) checks if two variables point to the same object in memory. Deep equality compares the actual structure and values recursively, requiring a custom function or library.

  • 98. What causes memory leaks in JavaScript?

    Common causes include unremoved event listeners, forgotten timers/intervals, unintended global variables, and closures retaining large objects longer than needed.

  • 99. What is the difference between `JSON.stringify` and `JSON.parse`?

    `JSON.stringify` converts a JavaScript value into a JSON string; `JSON.parse` converts a JSON string back into a JavaScript value. Functions and `undefined` are omitted during stringification.

  • 100. What is the difference between imperative and declarative programming?

    Imperative code specifies *how* to achieve a result step by step (e.g. a `for` loop). Declarative code specifies *what* the result should be, abstracting the steps (e.g. `array.map`). JavaScript supports both styles.

Notes

  • That's a complete set of 100 JavaScript interview questions with concise answers, organized across fundamentals, functions, objects/prototypes, arrays, async, ES6+, and advanced topics.