JavaScript Interview Questions and Answers (2026)
Master your frontend or full-stack interview with these 50 essential JavaScript interview questions. Detailed answers, code snippets, common pitfalls, and senior/lead engineering concepts.
Why JavaScript Mastery is Key to Passing Technical Interviews
JavaScript remains the undisputed language of the web. Whether you are interviewing for a Frontend, Full Stack, or Node.js Backend engineering role at top tech companies like Google, Meta, Amazon, Microsoft, Uber, or Netflix, your core JavaScript knowledge will be tested.
Interviewers ask JavaScript questions not just to see if you know the syntax, but to evaluate your mental model of:
- The Runtime Environment: How the browser or Node.js processes asynchronous operations (Event Loop, Call Stack, Task Queues).
- Memory Management: How closures, references, and scopes impact application scalability and memory leaks.
- Code Optimization: Your ability to write high-performance code under pressure using patterns like debouncing, throttling, and virtualization.
- Problem Solving & Adaptability: How you approach language edge cases, prototype inheritance, and scope boundaries.
This comprehensive guide compiles the top 50 JavaScript interview questions, organized by category, ranging from junior fundamentals to advanced architectural concepts.
---
Section 1: Fundamentals (Variables, Scope, Hoisting, Data Types)
Q1: What is the difference between `var`, `let`, and `const`?
- Difficulty: Easy
- Why Interviewers Ask It: To verify your understanding of block scope, re-assignment rules, and memory lifecycle in modern JS (ES6+).
- Detailed Answer:
varis function-scoped, can be redeclared, and is hoisted to the top of its scope, initialized asundefined.letis block-scoped, cannot be redeclared within the same scope, and is hoisted to the Temporal Dead Zone (TDZ).constis block-scoped, cannot be redeclared or reassigned, and must be initialized at declaration. It is also hoisted to the TDZ.- Common Mistakes: Thinking
constmakes objects immutable (only the reference binding is immutable, not the object keys). - Sample Interview Answer:
"Useconstby default to enforce immutability of references,letwhen you expect a variable to change, and avoidvarentirely to prevent accidental global leakage and scoping bugs due to hoisting."
Q2: What is Hoisting and the Temporal Dead Zone (TDZ)?
- Difficulty: Medium
- Why Interviewers Ask It: Evaluates your understanding of execution context phases.
- Detailed Answer:
- Hoisting is the JavaScript engine's behavior of moving declarations to the top of their enclosing scope during the compilation phase.
- Temporal Dead Zone (TDZ) is the block area from the start of the block until the variable is declared. Accessing a
letorconstvariable here throws aReferenceError. - Common Mistakes: Believing
letandconstare not hoisted. They are, but they are not initialized (unlikevarwhich getsundefined). - Sample Interview Answer:
console.log(a); // undefined (var is hoisted and initialized)
// console.log(b); // ReferenceError (b is in TDZ)
var a = 1;
let b = 2;
Q3: What is the difference between `==` and `===`?
- Difficulty: Easy
- Why Interviewers Ask It: Checks awareness of implicit type coercion.
- Detailed Answer:
==(loose equality) compares values after converting them to a common type (coercion).===(strict equality) compares both value and type without coercion.- Common Mistakes: Relying on
==for comparison, which leads to counter-intuitive cases (e.g.,[] == falseis true). - Sample Interview Answer:
"Always use===to prevent bugs caused by implicit coercion. The only widely accepted exception is comparing to null/undefined viaval == nullto catch both."
Q4: Explain the primitive data types in JavaScript.
- Difficulty: Easy
- Why Interviewers Ask It: Basic memory layout and type verification.
- Detailed Answer: JS has 7 primitive types:
string,number,boolean,undefined,null,symbol(unique identifiers), andbigint(arbitrary-precision integers). Primitives are immutable and stored directly on the stack. - Common Mistakes: Thinking
typeof nullis "null" (it returns"object"due to a legacy JS bug). - Sample Interview Answer:
"JavaScript has seven primitive types. They are passed by value and immutable. Everything else is a reference type (objects, arrays, functions) stored on the heap."
Q5: What is a Symbol and how is it used?
- Difficulty: Medium
- Why Interviewers Ask It: Checks modern ES6 knowledge and how to prevent object property collisions.
- Detailed Answer: A
Symbolis a unique and immutable primitive value. It is primarily used as unique keys for object properties to prevent naming collisions. - Common Mistakes: Trying to use
new Symbol()(it is a factory function, not a constructor). - Sample Interview Answer:
const myPrivateField = Symbol('id');
const obj = { [myPrivateField]: 123 };
console.log(obj[myPrivateField]); // 123
Q6: What is a BigInt and why is it needed?
- Difficulty: Easy
- Why Interviewers Ask It: Understanding limits of JS number representation.
- Detailed Answer: JavaScript's
numbertype represents double-precision floats, safe up to2^53 - 1(Number.MAX_SAFE_INTEGER).BigIntallows safe storage of integers beyond this limit. - Common Mistakes: Mixing
BigIntand standardNumberin arithmetic operations without explicit casting. - Sample Interview Answer:
"Create a BigInt by appendingnto an integer literal (e.g.,10n). It is essential for representing large database IDs or high-precision cryptographic values."
Q7: Explain Implicit Type Coercion.
- Difficulty: Medium
- Why Interviewers Ask It: Testing logic verification when handling operators.
- Detailed Answer: Coercion is the automatic conversion of values from one data type to another. For example, using
+with a string and a number coerces the number into a string ("5" + 2 = "52"), while subtraction-coerces strings to numbers ("5" - 2 = 3). - Common Mistakes: Forgetting that truthy/falsy values coerce in conditionals.
- Sample Interview Answer:
"Implicit coercion occurs when operators encounter mismatched types. Use explicit conversions likeNumber()orString()to keep operations predictable."
Q8: What are falsy values in JavaScript?
- Difficulty: Easy
- Why Interviewers Ask It: Basic control flow and default-assignment validation.
- Detailed Answer: There are exactly 8 falsy values:
false,0,-0,0n(BigInt zero),""(empty string),null,undefined, andNaN. Everything else is truthy. - Common Mistakes: Treating empty arrays
[]or empty objects{}as falsy (they are truthy). - Sample Interview Answer:
"The values that evaluate to false in a boolean context include false, zero variants, empty strings, null, undefined, and NaN. Be careful with empty arrays or objects, as they evaluate to truthy."
---
Section 2: Functions & Closures (Closures, Scope Chains, Currying)
Q9: What is a Closure? Explain with a practical code example.
- Difficulty: Medium
- Why Interviewers Ask It: A pillar JS concept. Tests encapsulation, memory containment, and function state preservation.
- Detailed Answer: A closure is the combination of a function bundled together with references to its surrounding state (the lexical environment). It gives an inner function access to the outer function's scope even after the outer function has returned.
- Common Mistakes: Causing memory leaks by retaining large, unneeded variables in a closure scope.
- Sample Interview Answer:
function createCounter() {
let count = 0; // encapsulated state
return {
increment: () => ++count,
decrement: () => --count,
getCount: () => count
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
Q10: What is a Higher-Order Function (HOF)?
- Difficulty: Easy
- Why Interviewers Ask It: Assesses functional programming capabilities.
- Detailed Answer: A Higher-Order Function is any function that takes one or more functions as arguments, returns a function as its result, or both. Examples include
map,filter, andreduce. - Common Mistakes: Not passing a callback function properly, causing execution crashes.
- Sample Interview Answer:
const numbers = [1, 2, 3];
const double = num => num * 2;
const doubled = numbers.map(double); // map is the HOF
Q11: Explain Function Currying and write a helper function to curry any function.
- Difficulty: Hard
- Why Interviewers Ask It: Demonstrates advanced functional programming and function argument manipulation.
- Detailed Answer: Currying transforms a function that takes multiple arguments into a sequence of nesting functions that each take a single argument.
- Common Mistakes: Not handling dynamic argument lengths or maintaining lexical
this. - Sample Interview Answer:
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return function(...nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
};
}
const sum = (a, b, c) => a + b + c;
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
Q12: What is the difference between Function Declarations and Function Expressions?
- Difficulty: Easy
- Why Interviewers Ask It: Scoping and hoisting lifecycle checks.
- Detailed Answer:
- Function Declarations are hoisted completely, meaning they can be called before their definition in the code.
- Function Expressions are not hoisted (they behave like let/const variables), meaning they throw a
ReferenceErrorif called before assignment. - Common Mistakes: Calling function expressions before they are initialized.
- Sample Interview Answer:
"Function declarations are fully hoisted and bind to the enclosing scope. Function expressions are treated as variable assignments and are only available after execution reaches their definition."
Q13: What is the difference between Call, Apply, and Bind?
- Difficulty: Medium
- Why Interviewers Ask It: Basic manipulation of execution context (
this). - Detailed Answer:
call()invokes a function immediately with a specifiedthisvalue and arguments passed individually.apply()invokes a function immediately with a specifiedthisvalue and arguments passed as an array.bind()returns a new copy of the function with thethisvalue permanently bound, to be executed later.- Common Mistakes: Forgetting that
bind()returns a function instead of executing it. - Sample Interview Answer:
const person = { name: 'Alice' };
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
greet.call(person, 'Hello', '!'); // call
greet.apply(person, ['Hi', '.']); // apply
const bound = greet.bind(person, 'Hey'); // bind
bound('?');
---
Section 3: Execution Model (Call Stack, Event Loop, Microtasks)
Q14: How does the JavaScript Event Loop work?
- Difficulty: Hard
- Why Interviewers Ask It: Core architecture question. Determines if you can write performant, non-blocking asynchronous operations.
- Detailed Answer:
- JS runs in a single-threaded runtime. Execution context is pushed onto the Call Stack.
- Async operations (Web APIs like setTimeout, fetch) run in the background.
- Once finished, their callbacks are queued in the Task Queues.
- The Event Loop continually checks the Call Stack. If the stack is empty, it flushes the Microtask Queue completely before taking one task from the Macrotask Queue.
- Common Mistakes: Blocking the event loop with synchronous computation, preventing UI rendering.
- Sample Interview Answer:
"The Event Loop coordinates code execution. It flushes the Call Stack, drains all microtasks (promises), allows the browser to re-render, and then executes the next macrotask (timers/I/O)."
+-------------------------------------------------+
| CALL STACK |
+-----------------------+-------------------------+
|
| (Async web API finishes)
v
+-----------------------+-------------------------+
| MICROTASK QUEUE (Promises) |
+-----------------------+-------------------------+
| (Flushed completely)
v
+-----------------------+-------------------------+
| MACROTASK QUEUE (Timers, I/O) |
+-----------------------+-------------------------+
| (One executed per loop)
v
[Render]
Q15: What is the difference between Macrotasks and Microtasks? Provide execution order.
- Difficulty: Hard
- Why Interviewers Ask It: Predict async code output accurately.
- Detailed Answer:
- Microtasks: High-priority execution. Includes
Promisecallbacks (.then,.catch,.finally),queueMicrotask, andMutationObserver. - Macrotasks: Low-priority execution. Includes
setTimeout,setInterval,setImmediate, and I/O tasks. - Common Mistakes: Thinking
Promiseexecutor code runs asynchronously (it runs synchronously; only the resolution callback runs asynchronously). - Sample Interview Answer:
console.log('1');
setTimeout(() => console.log('2'), 0); // Macrotask
Promise.resolve().then(() => console.log('3')); // Microtask
console.log('4');
// Output Order: 1, 4, 3, 2
Q16: What is a Stack Overflow in JavaScript?
- Difficulty: Easy
- Why Interviewers Ask It: Recursion boundary check.
- Detailed Answer: Occurs when the Call Stack exceeds its maximum limit, usually due to infinite recursion (calling a function without a base case).
- Common Mistakes: Not implementing a terminating condition in recursive routines.
- Sample Interview Answer:
"Stack overflow occurs when too many execution contexts are pushed onto the Call Stack. To prevent it, always ensure your recursive functions have a verified base case or utilize loop iterations for heavy computations."
Q17: Explain the creation and execution phases of Execution Context.
- Difficulty: Hard
- Why Interviewers Ask It: Deep JS compilation knowledge.
- Detailed Answer:
- Creation Phase: The compiler allocates memory for variables and functions (hoisting), sets up the Scope Chain, and determines the value of
this. - Execution Phase: The engine executes the code line-by-line, assigning values to variables and invoking functions.
- Common Mistakes: Thinking code runs without compilation (JS is compiled JIT right before execution).
- Sample Interview Answer:
"In the creation phase, the JS engine hoists functions and initialized variables. In the execution phase, it processes logic step-by-step. This separation explains TDZ and variable initialization behavior."
---
Section 4: Asynchronous JavaScript (Promises, Async/Await, Combinators)
Q18: What is a Promise? Explain its states.
- Difficulty: Easy
- Why Interviewers Ask It: Standard asynchronous logic implementation checks.
- Detailed Answer: A Promise represents the eventual completion (or failure) of an asynchronous operation and its resulting value. It has three states:
-
pending: Initial state, neither fulfilled nor rejected. -
fulfilled: Operation completed successfully. -
rejected: Operation failed.
- Common Mistakes: Forgetting to return promises inside
.thenchains, causing premature resolution. - Sample Interview Answer:
"A Promise wraps async logic, starting as pending and resolving into either fulfilled or rejected. Once settled, its state cannot be modified."
Q19: Explain the difference between `Promise.all`, `Promise.allSettled`, `Promise.any`, and `Promise.race`.
- Difficulty: Medium
- Why Interviewers Ask It: Checks control over concurrent async actions.
- Detailed Answer:
Promise.all: Resolves when *all* promises resolve. Rejects immediately if *any* promise rejects.Promise.allSettled: Resolves when *all* settle (either resolve or reject) with an array of statuses.Promise.any: Resolves as soon as the *first* promise resolves. Rejects only if *all* reject.Promise.race: Settles as soon as the *first* promise settles (either resolves or rejects).- Common Mistakes: Using
Promise.allwhen you need some actions to fail silently without aborting the entire sequence. - Sample Interview Answer:
// Use Promise.allSettled when you want to execute multiple independent requests
// and analyze their individual results regardless of failure.
const results = await Promise.allSettled([p1, p2, p3]);
Q20: How does `async/await` handle errors under the hood?
- Difficulty: Medium
- Why Interviewers Ask It: Error handling cleanliness and async stack traces.
- Detailed Answer:
async/awaitis syntactic sugar over Promise chaining. Async functions implicitly return a promise. Errors inside async functions reject the returned promise, which must be caught usingtry/catchblocks. - Common Mistakes: Not wrapping async await in
try/catch, leading to unhandled promise rejections. - Sample Interview Answer:
async function fetchData() {
try {
const response = await fetch('/api');
return await response.json();
} catch (err) {
console.error('Fetch failed:', err);
}
}
Q21: What is a Promise Race condition? How can you cancel a Promise?
- Difficulty: Hard
- Why Interviewers Ask It: Testing your ability to prevent memory leaks and outdated responses in fast-changing UIs.
- Detailed Answer: A race condition occurs when asynchronous operations settle out of order. You cannot force a Native JS Promise to terminate, but you can cancel the underlying async operation using an
AbortController. - Common Mistakes: Letting old search queries resolve and overwrite the latest search results on slow connections.
- Sample Interview Answer:
const controller = new AbortController();
fetch('/api', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') console.log('Cancelled!');
});
controller.abort(); // Cancels the request
---
Section 5: Objects & Prototypes (Prototype Chain, `this` Binding)
Q22: What is Prototype Inheritance and the Prototype Chain?
- Difficulty: Medium
- Why Interviewers Ask It: Testing fundamental understanding of JS object-oriented model.
- Detailed Answer: Every object in JS has an internal property pointing to another object called its prototype (
__proto__). When resolving properties, JS traverses up this chain until it finds the property or reachesnull. - Common Mistakes: Modifying built-in prototypes like
Object.prototype, which pollutes scope. - Sample Interview Answer:
const animal = { eats: true };
const rabbit = Object.create(animal); // sets animal as prototype
console.log(rabbit.eats); // true (inherited)
console.log(rabbit.__proto__ === animal); // true
Q23: How does the `this` keyword resolve inside a nested function?
- Difficulty: Medium
- Why Interviewers Ask It: Evaluates comprehension of execution contexts.
- Detailed Answer: Standard functions bind
thisdynamically depending on how they are called. A nested standard function inside a method loses its implicit binding and defaults to the global object (windoworundefinedin strict mode). Arrow functions fix this by inheritingthislexically from their parent context. - Common Mistakes: Expecting
thisinside a nested helper function to refer to the parent object. - Sample Interview Answer:
const obj = {
name: 'Alice',
greet() {
// Arrow function inherits 'this' from greet context
const inner = () => console.log(this.name);
inner();
}
};
obj.greet(); // Alice
Q24: What is the difference between `__proto__` and `prototype`?
- Difficulty: Hard
- Why Interviewers Ask It: Clears common confusion in JS OOP classes.
- Detailed Answer:
__proto__(dunder proto) is the actual getter/setter link on an object instance pointing to its prototype.prototypeis a property unique to constructor functions (or classes) that determines what__proto__link will be assigned to instances created using thenewoperator.- Common Mistakes: Looking for the
prototypeproperty on a regular object instance. - Sample Interview Answer:
"An instance's__proto__points to its creator'sprototype. E.g.,let arr = []; arr.__proto__ === Array.prototypeis true."
Q25: Explain Object descriptors and how to freeze an object.
- Difficulty: Hard
- Why Interviewers Ask It: Tests state preservation and library creation concepts.
- Detailed Answer:
Object.freeze()makes an object completely immutable (no additions, deletions, or edits).Object.seal()prevents adding/deleting properties but allows editing existing values.- Common Mistakes: Thinking
Object.freeze()is recursive (it is shallow; nested objects can still be modified). - Sample Interview Answer:
const obj = { nested: { a: 1 } };
Object.freeze(obj);
obj.nested.a = 2; // works! Freeze is shallow
---
Section 6: ES6+ (let/const, Arrow Functions, Spread/Rest)
Q26: Explain the difference in `this` binding between Arrow Functions and Regular Functions.
- Difficulty: Easy
- Why Interviewers Ask It: Basic modernization check.
- Detailed Answer: Regular functions define
thisdynamically based on execution call-site. Arrow functions bindthislexically, inheriting it from the scope in which they were defined. Arrow functions cannot be bound usingcall(),apply(), orbind(). - Common Mistakes: Using arrow functions for object methods that rely on the object's instance context.
- Sample Interview Answer:
"Regular functions bindthisat call-time. Arrow functions capturethislexically at creation-time, making them perfect for callbacks inside class methods or timers."
Q27: What is the difference between Spread (`...`) and Rest (`...`) operators?
- Difficulty: Easy
- Why Interviewers Ask It: Verifies clean parameter and array destruction code patterns.
- Detailed Answer:
- Spread expands elements (arrays, objects) into individual items (e.g.,
[...arr]). - Rest collects multiple elements into a single array structure (e.g.,
function sum(...nums)). - Common Mistakes: Placing the rest parameter somewhere other than the last position in function parameters.
- Sample Interview Answer:
"Spread unpacks items, while Rest packs them. Use Spread to clone arrays or merge objects, and Rest to collect dynamic arguments inside functions."
Q28: How does Destructuring work with alias mapping and default values?
- Difficulty: Easy
- Why Interviewers Ask It: Checks code readability and clean refactoring patterns.
- Detailed Answer: Destructuring allows unpacking values from arrays or properties from objects into distinct variables, supporting custom naming (aliases) and fallbacks.
- Common Mistakes: Destructuring
nullorundefined, which throws a runtime crash. - Sample Interview Answer:
const user = { name: 'Bob' };
const { name: userName, age = 25 } = user; // Alias and Default
console.log(userName, age); // Bob, 25
---
Section 7: Performance (Debouncing, Throttling, Memory Leaks)
Q29: Implement a Debounce function and explain its use case.
- Difficulty: Medium
- Why Interviewers Ask It: Standard performance question. Tests timer logic, closure references, and execution delays.
- Detailed Answer: Debouncing delays invoking a function until after a specific amount of time has elapsed since the last time it was called. It is ideal for search auto-suggest boxes.
- Common Mistakes: Losing the context of
thisor arguments inside the debounced helper wrapper. - Sample Interview Answer:
function debounce(fn, delay) {
let timerId;
return function(...args) {
clearTimeout(timerId);
timerId = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
Q30: Implement a Throttle function and explain its use case.
- Difficulty: Hard
- Why Interviewers Ask It: Performance scaling tests. Tests handling events like scroll, resize, or drag-and-drop.
- Detailed Answer: Throttling guarantees a function is executed at most once in a specified time interval, ignoring repeated calls within that window.
- Common Mistakes: Not executing the final call if it falls outside the throttle window.
- Sample Interview Answer:
function throttle(fn, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
Q31: What are the main causes of memory leaks in JavaScript?
- Difficulty: Medium
- Why Interviewers Ask It: Production-grade architecture verification.
- Detailed Answer:
- Accidental global variables (not using let/const).
- Uncleared interval timers or callbacks.
- Out-of-DOM references (holding DOM element nodes in memory).
- Uncleared event listeners on unmounted components (in SPAs).
- Common Mistakes: Creating intervals in components and forgetting to run
clearIntervalon unmount. - Sample Interview Answer:
"Memory leaks occur when references are no longer needed but are still retained in memory. Prevent them by clearing timers, unsubscribing from event listeners, and scoping variables strictly."
---
Section 8: Browser Concepts & DOM
Q32: What is the difference between Event Bubbling and Event Capturing?
- Difficulty: Easy
- Why Interviewers Ask It: Basic DOM event flow verification.
- Detailed Answer:
- Capturing Phase: Events travel down from the window element, through ancestors, to the target.
- Bubbling Phase: Events travel up from the target, back up through ancestors, to the window.
- Common Mistakes: Thinking events capture and bubble at the same time (capturing occurs first, then bubbling).
- Sample Interview Answer:
"Events start in the capturing phase traveling downward, and transition to the bubbling phase rising upward. Add listener on capturing phase by setting the third parameteruseCapturetotrue."
Q33: What is Event Delegation and why is it beneficial?
- Difficulty: Medium
- Why Interviewers Ask It: Scalability of DOM bindings check.
- Detailed Answer: Event delegation is a pattern of attaching a single event listener to a parent element instead of attaching multiple listeners to individual child elements. It leverages event bubbling.
- Common Mistakes: Not checking
event.targetmatch properties, causing random handlers to execute. - Sample Interview Answer:
document.getElementById('parent-list').addEventListener('click', (e) => {
if (e.target && e.target.nodeName === 'LI') {
console.log('List item clicked:', e.target.innerText);
}
});
Q34: What is the difference between `stopImmediatePropagation()` and `stopPropagation()`?
- Difficulty: Medium
- Why Interviewers Ask It: Fine control over event lifecycle checks.
- Detailed Answer:
stopPropagation()prevents the event from traveling up or down the DOM tree (bubbles/capturing stops).stopImmediatePropagation()does that, and also blocks any *other* listeners attached to the *same* element from running.- Common Mistakes: Assuming
stopPropagation()blocks other listeners on the current element. - Sample Interview Answer:
"UsestopPropagationto prevent bubbling to parent elements. UsestopImmediatePropagationif you want to abort other handlers on the same element from executing immediately."
---
Section 9: Advanced Concepts (Map vs Set, WeakMap, Generators)
Q35: What is the difference between `Map` and `Object`?
- Difficulty: Easy
- Why Interviewers Ask It: Data structure optimization checks.
- Detailed Answer:
Mapkeys can be of any type (including functions/objects). It maintains insertion order and has direct size retrieval (map.size).Objectkeys can only be strings or symbols, and it does not guarantee insertion order.- Common Mistakes: Using
Objectfor dynamic dictionary maps when key types can vary or require clean preservation of order. - Sample Interview Answer:
"Use Map when you need dynamic key-value pairs with non-string keys or require frequent insertion/deletion, as it performs better at scale."
Q36: What is a `WeakMap` and when would you use it?
- Difficulty: Hard
- Why Interviewers Ask It: Memory profiling and garbage collection patterns.
- Detailed Answer: A
WeakMapis a collection of key-value pairs where the keys must be objects and are held as weak references. If the key object has no other references, it is garbage collected, automatically deleting the key-value pair from the map. - Common Mistakes: Trying to use primitives (like strings) as keys in a
WeakMap. - Sample Interview Answer:
"Use WeakMap for caching data or storing metadata for objects without blocking garbage collection (e.g., storing private metadata about DOM nodes)."
Q37: How do Generator functions work?
- Difficulty: Hard
- Why Interviewers Ask It: Advanced control flows, custom iterables.
- Detailed Answer: Generator functions can stop execution midway and resume later. Declared with
function*, they return a Generator object and use theyieldkeyword to return values sequentially. - Common Mistakes: Forgetting that generators are stateful and return an iterator (calling next() moves the state forward).
- Sample Interview Answer:
function* idGenerator() {
let id = 1;
while (true) yield id++;
}
const gen = idGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
Q38: Explain the difference between Shallow Copy and Deep Copy.
- Difficulty: Medium
- Why Interviewers Ask It: Reference mutability checks.
- Detailed Answer:
- Shallow Copy: Copies top-level values. Nested objects still share references. (e.g.,
{...obj}orObject.assign()). - Deep Copy: Recursively copies all properties. No references are shared. (e.g.,
structuredClone(obj)or custom recursion). - Common Mistakes: Using
JSON.parse(JSON.stringify(obj))for deep copies when the object contains functions, Date objects, or undefined values (they get lost or distorted). - Sample Interview Answer:
"Use shallow copy for flat objects. For nested objects, use the modern native structuredClone() to deep copy without losing standard data types."
Q39: What is Currying vs Partial Application?
- Difficulty: Medium
- Why Interviewers Ask It: Structural difference check in functional design.
- Detailed Answer:
- Currying: Converts
f(a, b, c)tof(a)(b)(c). (Always returns nested functions accepting exactly 1 parameter). - Partial Application: Binds some arguments of a function, returning a new function that takes the *remaining* arguments. (e.g.,
f(a, b, c)becomesf(a, b)(c)orf(a)(b, c)). - Common Mistakes: Conflating these two terms in functional programming.
- Sample Interview Answer:
"Currying converts a function of arity N into N functions of arity 1. Partial application binds a subset of parameters, returning a function of smaller arity."
Q40: What is a Pure Function and what are side effects?
- Difficulty: Easy
- Why Interviewers Ask It: Functional programming fundamentals.
- Detailed Answer: A pure function always returns the same output for the same input and has no side effects (no DOM manipulation, network requests, state updates, or database writes).
- Common Mistakes: Accessing variable state outside the scope of the function, which breaks purity.
- Sample Interview Answer:
"Pure functions make code predictable and testable. They do not read or modify external state and do not cause side effects."
---
Section 10: OOP & Classes
Q41: How do JavaScript ES6 Classes differ from Constructor Functions?
- Difficulty: Medium
- Why Interviewers Ask It: Checking if you understand that classes are syntactic sugar.
- Detailed Answer: ES6 classes are syntactic sugar over prototypal inheritance. However:
- Classes enforce
new(calling them without throws a TypeError). - Class methods are non-enumerable.
- Classes run in strict mode by default.
- Common Mistakes: Believing JS has traditional class-based inheritance like Java (it is still prototype-based inheritance underneath).
- Sample Interview Answer:
"Classes provide cleaner syntax but are prototypal. They enforce strict mode, prevent invocation without new, and make method inheritance clean."
Q42: What is the `super` keyword in JavaScript?
- Difficulty: Easy
- Why Interviewers Ask It: Inheritance subclassing check.
- Detailed Answer:
superinvokes the constructor of the parent class. In a subclass, you must callsuper()before referencingthisin the constructor. - Common Mistakes: Accessing
thisin a subclass constructor before callingsuper(). - Sample Interview Answer:
class Animal { constructor(name) { this.name = name; } }
class Dog extends Animal {
constructor(name, breed) {
super(name); // parent call
this.breed = breed;
}
}
Q43: How do you declare private fields in modern JS classes?
- Difficulty: Easy
- Why Interviewers Ask It: modern ES2022 features checks.
- Detailed Answer: Use the hash symbol
#prefix before the field name. These variables are completely encapsulated and inaccessible from outside the class. - Common Mistakes: Thinking prepended underscores (
_privateField) are private (they are just developer conventions and still fully public). - Sample Interview Answer:
class BankAccount {
#balance = 0; // Private field
deposit(amount) { this.#balance += amount; }
}
Q44: What is the difference between Static Methods and Instance Methods?
- Difficulty: Easy
- Why Interviewers Ask It: Structural class knowledge.
- Detailed Answer:
- Static Methods are attached directly to the class definition (e.g.
Math.max()). They cannot access instance properties. - Instance Methods are attached to the prototype and called on instances of the class.
- Common Mistakes: Calling static methods on instances of the class instead of the class name directly.
- Sample Interview Answer:
"Static methods are defined with the static keyword and exist on the class itself, not on instances. Use them for helper functions."
---
Section 11: Google & Meta Style JavaScript Questions
Q45: Implement a custom Promise class from scratch.
- Difficulty: Hard
- Why Interviewers Ask It: Common Google/Uber question. Tests deep understanding of microtask queuing, state mutations, and async callbacks.
- Detailed Answer: A basic implementation of a Promise requires storing state, values, callbacks, and wrapping completion in a microtask.
- Common Mistakes: Executing callbacks synchronously instead of deferring them as microtasks.
- Sample Interview Answer:
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.handlers = [];
const resolve = (val) => {
if (this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = val;
this.handlers.forEach(h => queueMicrotask(h));
};
executor(resolve);
}
then(callback) {
return new MyPromise((res) => {
const handler = () => res(callback(this.value));
if (this.state === 'fulfilled') queueMicrotask(handler);
else this.handlers.push(handler);
});
}
}
Q46: Implement a deep comparison function (`deepEqual(a, b)`).
- Difficulty: Hard
- Why Interviewers Ask It: Meta/Airbnb style. Tests recursion, object type checks, and handling nested references.
- Detailed Answer: Deep equality requires verifying primitives match exactly, and recursing on properties of objects and arrays.
- Common Mistakes: Failing to check if constructors match or ignoring
null(sincetypeof null === 'object'). - Sample Interview Answer:
function deepEqual(a, b) {
if (a === b) return true;
if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) return false;
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (let key of keysA) {
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
}
return true;
}
Q47: Implement a Memoize helper function.
- Difficulty: Medium
- Why Interviewers Ask It: Tests caching closures and key generation.
- Detailed Answer: Memoization caches the output of a function based on arguments.
- Common Mistakes: Not handling multiple argument keys correctly.
- Sample Interview Answer:
function memoize(fn) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
Q48: Flatten a nested array recursively (without using `Array.prototype.flat()`).
- Difficulty: Easy
- Why Interviewers Ask It: Basic recursion and array iteration checks.
- Detailed Answer: Recursively loop through arrays and append non-array elements to the collector.
- Common Mistakes: Not using recursion correctly.
- Sample Interview Answer:
function flatten(arr) {
return arr.reduce((acc, val) =>
Array.isArray(val) ? acc.concat(flatten(val)) : acc.concat(val), []
);
}
Q49: Explain the difference between microtask throttling and standard throttling.
- Difficulty: Hard
- Why Interviewers Ask It: High-performance browser rendering check.
- Detailed Answer:
- Standard throttling uses
setTimeout(macrotask), which can fall out of sync with browser paint cycles. - Microtask throttling uses
requestAnimationFrame(rAF), executing right before the browser repaints, making it perfectly performant for UI updates. - Common Mistakes: Using setTimeout for smooth animation rendering.
- Sample Interview Answer:
"UserequestAnimationFrameinstead ofsetTimeoutfor UI-bound throttling, as it triggers changes synchronized with the screen's refresh rate."
Q50: How do you check if a value is an Array?
- Difficulty: Easy
- Why Interviewers Ask It: Simple type checking quirks.
- Detailed Answer: Use
Array.isArray(val). Do not usetypeof(which returns"object"). - Common Mistakes: Using
instanceof Array(can fail when comparing objects across different browser iframes). - Sample Interview Answer:
"Always use Array.isArray() to check values, as it is the most reliable built-in helper across environment contexts."
---
Senior JavaScript Interview Questions
- Explain the V8 engine compilation pipeline: Discuss Ignition interpreter, TurboFan compiler, hot functions, and de-optimization behaviors.
- How would you implement a custom Garbage Collection detection mechanism? Discuss using
FinalizationRegistryto track object cleanup. - Explain the difference between Service Workers, Web Workers, and Worklets: Web Workers run scripts in background threads; Service Workers intercept network requests; Worklets are hook points into browser rendering pipeline.
- Implement custom module federation resolver: How micro-frontends share JavaScript bundles dynamically.
---
Google & Meta Style Practice Questions
- Distributed event emitter: Build an event emitter that coordinates events across multiple browser windows using
BroadcastChannel. - Trie-based autocomplete: Implement a client-side search indexing engine that operates with O(K) lookup constraints.
- Visual viewport virtualization: Build an infinite scroll system that virtualizes elements to keep memory footprints constant.
---
Quick Revision Notes
- TDZ: Variable exists but cannot be accessed until initialization line.
- Microtasks > Macrotasks: Event loop drains all microtasks first.
- Closures retain outer variables: Can cause leaks if outer scope references stay active.
- Arrow functions do not bind
this: They inherit it from parent context lexically. - shallow clone !== deep clone: structuredClone preserves nested formats.
---
5 Practical Interview Tips
- Vocalize constraints: Always discuss complexity (Time & Space) before writing code.
- Draw first: Explain the event loop execution flows or prototype inheritance chains visually.
- Narrate your logic: Avoid long silent coding blocks. Tell the interviewer what you are writing.
- Review your code: Trace values manually with simple parameters before declaring your code complete.
- Admit limits: If you do not know a native implementation, discuss the mental logic of the approach.
---
Frequently Asked Questions (FAQs)
#### Q: How does JavaScript execute asynchronous code if it is single-threaded?
A: The JS engine itself is single-threaded (Call Stack), but the surrounding environment (Browser/Node) provides multithreaded APIs (timers, network, file operations). When async tasks complete, their callbacks are queued and executed on the JS main thread via the Event Loop.
#### Q: What is the main cause of memory leaks with closures?
A: Storing functions inside active objects that retain references to large parameters in their lexical environment, preventing the garbage collector from reclaiming that memory.
#### Q: Can const variables change value?
A: For primitive values (like numbers or strings), no. For reference values (objects, arrays), yes. You cannot reassign the variable name to point to a new value, but you can mutate the object's properties or push values to the array.
#### Q: What is the difference between Object.create and new?
A: Object.create(proto) directly creates a new object with the specified prototype. new Constructor() executes the constructor function, sets this to point to a new instance whose prototype is bound, and returns the instance.
---
Ready to Test Your JavaScript Skills?
Mastering the theory is only half the battle. To pass your technical rounds at top product companies, you need to perform under pressure.
Try InterviewMantra's AI-Powered Mock Interviews
- Real-time adaptation: The AI interviewer adjusts the difficulty of questions dynamically based on your performance.
- In-depth reports: Get structured analysis on your problem-solving approaches, coding quality, and time complexities.
- Code Execution support: Code directly in our built-in Monaco editor and run your scripts against live cases.
[👉 Try a Free AI Mock Interview Now](https://interviewmantra.in/register)
Frequently Asked Questions
How does JavaScript execute asynchronous code if it is single-threaded?
The JS engine itself is single-threaded (Call Stack), but the surrounding environment (Browser/Node) provides multithreaded APIs (timers, network, file operations). When async tasks complete, their callbacks are queued and executed on the JS main thread via the Event Loop.
What is the main cause of memory leaks with closures?
Storing functions inside active objects that retain references to large parameters in their lexical environment, preventing the garbage collector from reclaiming that memory.
Can const variables change value?
For primitive values (like numbers or strings), no. For reference values (objects, arrays), yes. You cannot reassign the variable name to point to a new value, but you can mutate the object's properties or push values to the array.
What is the difference between Object.create and new?
Object.create(proto) directly creates a new object with the specified prototype. new Constructor() executes the constructor function, sets this to point to a new instance whose prototype is bound, and returns the instance.