25 Intermediate to MAANG-Level JavaScript Interview Questions (With Code Examples)
Introduce the goal: Mastering intermediate to advanced JavaScript interview questions
- What is JavaScript and how does it work?
- JavaScript is a high-level, single-threaded, event-driven language used for web development.
console.log("Hello, World!"); //simple javascript execution.2. Difference between var, let, and const
var, let, and const — scope, reassignment, and modern best practices.var a = 1;
let b = 2;
const c = 3;3. What is hoisting in JavaScript?
Get Prashant Praveen’s stories in your inbox
Join Medium for free to get updates from this writer.
Hoisting is JavaScript’s default behavior of moving declarations to the top of their scope.
console.log(x); // undefined
var x = 5;4. What is Closure? Explain with Code
- Creates private variables that cannot be accessed directly from outside
function outer() {
let count = 0;
return function inner() {
count++;
return count;
};
}
const counter = outer();
console.log(counter()); // 15. Explain the event loop in JavaScript
- The event loop allows JavaScript to handle asynchronous operations.
console.log("Start");
setTimeout(() => console.log("Async"), 0);
console.log("End");
//Output
//Start
//End
//Async6. What is the this keyword?
- this refers to the object that is executing the current function.
const obj = {
name: "JS",
getName() {
return this.name;
}
};7. Difference Between map(), filter(), reduce()
//Map
const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2);
console.log(doubled); // [2, 4, 6] --Transform each element in an array
//Filter
const nums = [1, 2, 3, 4];
const even = nums.filter(n => n % 2 === 0);
console.log(even); // [2, 4] --Select elements based on a condition
//Reduce
const nums = [1, 2, 3, 4];
const sum = nums.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 10 --Reduce array8. What will be the output of the following JavaScript code?
var a = 1;
function test() {
console.log(a); //undefined
var a = 2;
}
test();Difficult JavaScript Interview Questions (Senior Level)
9. Implement a Custom bind() Method
Function.prototype.myBind = function (context, ...args) {
const fn = this;
return function (...newArgs) {
return fn.apply(context, [...args, ...newArgs]);
};
};8. Flatten a Nested Array (Infinite Depth)
function flatten(arr) {
return arr.reduce((acc, val) =>
Array.isArray(val)
? acc.concat(flatten(val))
: acc.concat(val), []
);
}
//input = [23, 45,[21, [33, 22], 20]
//output = [23, 45, 21, 33, 22, 20]9. Implement Memoization Function
function memoize(fn) {
const cache = {};
return function (x) {
if (cache[x]) return cache[x];
return (cache[x] = fn(x));
};
}10. Explain and Implement call, apply, and bind
//Call is function immediately with given this and arguments
const person = { name: "Mani" };
function greet(age) {
console.log(`Hi ${this.name}, age ${age}`);
}
greet.call(person, 25);
//Apply same as call, but arguments are passed as an array
greet.apply(person, [25]);
//Bind returns a new function (does NOT execute immediately)
const boundFn = greet.bind(person, 25);
boundFn();11. Create a Custom setInterval
function customInterval(fn, delay) {
let timer;
function run() {
timer = setTimeout(() => {
fn();
run();
}, delay);
}
run();
return () => clearTimeout(timer);
}12. Implement Promise.all()
function promiseAll(promises) {
return new Promise((resolve, reject) => {
let results = [];
let completed = 0;
promises.forEach((p, i) => {
Promise.resolve(p)
.then((res) => {
results[i] = res;
completed++;
if (completed === promises.length) resolve(results);
})
.catch(reject);
});
});
}13. What is Currying?
function curry(a) {
return function (b) {
return function (c) {
return a + b + c;
};
};
}14. Deep Clone an Object
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}Advanced JavaScript Interview Questions (MAANG Level)
15. Implement Promise.allsettled()
function promiseAllSettled(promises) {
return Promise.all(
promises.map(p =>
Promise.resolve(p)
.then(value => ({ status: "fulfilled", value }))
.catch(reason => ({ status: "rejected", reason }))
)
);
}16. What is Overloading?
- Flexibility in JS functions
- Handling dynamic arguments
function sum(...args) {
if (args.length === 2) return args[0] + args[1];
if (args.length === 3) return args[0] + args[1] + args[2];
}17. StructuredClone (Modern JS)
const obj = { a: 1, b: { c: 2 } };
const clone = structuredClone(obj);18. What is Object.create() and Object.freeze().
Object.create()setspersonas the prototype ofuseruserinherits methods via the prototype chainObject.freeze():- Prevents modification ❌
- Prevents addition ❌
- Prevents deletion ❌
// object create
const person = {
greet() {
return "Hello";
}
};
const user = Object.create(person);
console.log(user.greet()); // Hellp
//object Freeze
const obj = { name: "JS" };
Object.freeze(obj);
obj.name = "React";
obj.age = 10;
console.log(obj); //{ name: "JS }19. Implement Promise.any()
function promiseAny(promises) {
return new Promise((resolve, reject) => {
let errors = [];
let count = 0;
promises.forEach((p, i) => {
Promise.resolve(p)
.then(resolve)
.catch(err => {
errors[i] = err;
count++;
if (count === promises.length) {
reject(new AggregateError(errors));
}
});
});
});
}20. Build a Virtual DOM Diff Algorithm (Basic)
- Compare oldTree vs newTree and return minimal changes (patches).
//VDOM NODE
function h(type, props = {}, children = []) {
return { type, props, children };
}
//Diff
function diff(oldNode, newNode) {
if (!newNode) return { type: "REMOVE" };
if (!oldNode) return { type: "ADD", newNode };
if (oldNode.type !== newNode.type)
return { type: "REPLACE", newNode };
return {
type: "UPDATE",
props: diffProps(oldNode.props, newNode.props),
children: diffChildren(oldNode.children, newNode.children),
};
}
//Props
function diffProps(a, b) {
const p = {};
for (let k in b) if (b[k] !== a[k]) p[k] = b[k];
for (let k in a) if (!(k in b)) p[k] = null;
return p;
}
//children
function diffChildren(a = [], b = []) {
const res = [];
const n = Math.max(a.length, b.length);
for (let i = 0; i < n; i++) res.push(diff(a[i], b[i]));
return res;
}
21. Implement Lazy Loading with Intersection Observer
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});22. Create Your Own async/await Using Generators
function asyncWrapper(generatorFn) {
return function () {
const gen = generatorFn.apply(this, arguments);
function handle(result) {
if (result.done) return Promise.resolve(result.value);
return Promise.resolve(result.value).then(
res => handle(gen.next(res)),
err => handle(gen.throw(err))
);
}
return handle(gen.next());
};
}23. Implement a Promise Pool (Concurrency Control)
async function promisePool(tasks, limit) {
let i = 0;
const results = [];
async function worker() {
while (i < tasks.length) {
const currentIndex = i++;
results[currentIndex] = await tasks[currentIndex]();
}
}
const workers = Array(limit).fill(0).map(worker);
await Promise.all(workers);
return results;
}24. Detect Circular References in an Object
function hasCycle(obj, seen = new Set()) {
if (obj && typeof obj === "object") {
if (seen.has(obj)) return true;
seen.add(obj);
for (let key in obj) {
if (hasCycle(obj[key], seen)) return true;
}
seen.delete(obj);
}
return false;
}25. Implement a JavaScript Scheduler with Priority
class Scheduler {
constructor() {
this.queue = [];
this.running = false;
}
add(task, priority = 0) {
this.queue.push({ task, priority });
this.queue.sort((a, b) => b.priority - a.priority);
this.run();
}
async run() {
if (this.running) return;
this.running = true;
while (this.queue.length) {
const { task } = this.queue.shift();
await task();
}
this.running = false;
}
}FAQ Section
1. What are the most important intermediate to advanced JavaScript interview questions?
Answer: The most important JavaScript interview questions include concepts like closures, event delegation, debouncing, hoisting, and array methods (map, filter, reduce). At advanced levels, interviewers focus on topics like the event loop, promises (Promise.all, Promise.any), currying, throttling, and custom polyfills. Mastering these concepts with real-world code examples significantly improves your chances of cracking MAANG-level interviews.
2. How do closures work in JavaScript with real-world use cases?
Answer: A closure is created when a function retains access to its lexical scope even after the outer function has executed. It is commonly used for data encapsulation and state management. For example, a counter function can maintain a private variable without exposing it globally, making closures essential for building secure and modular JavaScript applications.
3. What is the difference between debouncing and throttling in JavaScript?
Answer: Debouncing ensures that a function executes only after a specified delay once the user stops triggering an event, making it ideal for search inputs. Throttling limits the execution of a function to once in a given time interval, which is useful for scroll or resize events. Both techniques improve performance and are commonly asked in advanced JavaScript interviews.
4. How does the JavaScript event loop work?
Answer: The JavaScript event loop manages asynchronous operations by handling the call stack, microtask queue (Promises), and callback queue (setTimeout, setInterval). It ensures non-blocking execution by prioritizing microtasks before processing callbacks. Understanding the event loop is crucial for solving complex async behavior questions in senior and MAANG-level interviews.
5. What are some advanced JavaScript coding problems asked in MAANG interviews?
Answer: Advanced JavaScript interview questions include implementing Promise.all, Promise.any, custom bind, deep cloning objects, memoization, flattening nested arrays, building schedulers, and creating async/await using generators. These problems test deep knowledge of JavaScript internals, performance optimization, and problem-solving skills required for top tech companies.






