Learn Key JavaScript Concepts: 100+ Interview Questions with & Code Examples
Dive into JavaScript: 100+ Key Interview Questions with Code Answers
Table of contents
- Basic task-based 60 questions
- 1. Variable Declaration
- 2. Hoisting
- 3. Closures
- 4. Event Loop
- 5. Prototypal Inheritance
- 6. Callback Functions
- 7. Promises
- 8. Async/Await
- 9. Array Methods
- 10. Destructuring
- 11. Rest and Spread Operators
- 12. ES6 Classes
- 13. Debouncing
- 14. Throttling
- 15. Default Parameters
- 16. Template Literals
- 17. Object Methods
- 18. Optional Chaining
- 19. Nullish Coalescing Operator
- 20. Spread with Objects
- 21. Symbol
- 22. Iterators
- 23. Generators
- 24. Set
- 25. Map
- 26. WeakMap and WeakSet
- 27. This Keyword
- 28. Arrow Functions
- 29. Function Currying
- 30. Event Delegation
- 31. Deep and Shallow Copy
- 32. JSON Methods
- 33. Module System
- 34. Web Storage API
- 35. Fetch API with Error Handling
- 36. Async/Await with Error Handling
- 37. DOM Manipulation
- 38. Event Listeners
- 39. Prevent Default Behavior
- 40. Bubbling and Capturing
- 41. Custom Events
- 42. Date and Time
- 43. Regular Expressions
- 44. Error Handling
- 45. Constructor Functions
- 46. ES6 Set Timeout/Interval
- 47. Call, Apply, and Bind
- 48. Polyfills
- 49. Object Freezing
- 50. Promises in Sequence
- 51. Throttling
- 52. Debouncing
- 53. Function Composition
- 54. Hoisting
- 55. Closures
- 56. Promises with All, AllSettled, Race, and Any
- 57. Event Loop
- 58. Callbacks
- 59. Strict Mode
- 60. Asynchronous Iteration
- Advanced JavaScript Questions and Answers
- 1. What is Currying? Implement it.
- 2. What is Memoization? Implement a memoized function.
- 3. Explain Prototypal Inheritance with an Example.
- 4. Implement a Custom Promise.all Method.
- 5. Implement a Singleton Pattern.
- 6. What are WeakMap and WeakSet? Use Cases.
- 7. Explain Debounce and Implement It Using Promises.
- 8. What is a Proxy? Implement a Logging Proxy.
- 9. Explain Tail Call Optimization with an Example.
- 10. Implement an Event Emitter.
- 11. Explain and Implement Generators.
- 12. What are Iterators? Implement a Custom Iterator.
- 13. Implement a Deep Clone Function.
- 14. Explain the Difference Between Call, Apply, and Bind.
- 15. What is a Symbol? Use Case.
- 16. Implement a Rate Limiter Using Closures.
- 17. Explain Async/Await Error Handling with Examples.
- 18. What is Object.freeze? Demonstrate Its Use.
- 19. Implement a Custom Map Function.
- 20. Explain Event Delegation with an Example.
- 21. Implement a Retry Mechanism for Failed Promises.
- 22. What Are Mixins? Implement One.
- 23. Implement a Custom Reduce Function.
- 24. Explain the Module Pattern.
- 25. Implement a Custom Event Bus.
- 26. Explain and Implement Throttling.
- 27. Explain Reflect and Its Use Cases.
- 28. What is the Difference Between == and ===?
- 29. Implement a Custom Promise.race Method.
- 30. Explain the Observer Pattern. Implement It.
- 31. Explain Set and Map. When Should You Use Them?
- 32. What Are Optional Chaining and Nullish Coalescing?
- 33. Implement a Custom Flatten Function for Nested Arrays.
- 34. What Are Tagged Templates?
- 35. Explain Object.create and Its Use Cases.
- 36. What Are Generators in JavaScript?
- 37. What Is the Purpose of Symbol.iterator?
- 38. What Is Hoisting?
- 39. What Are JavaScript Modules?
- 40. What Is the Purpose of Object.seal?
Introduction
Hello fellow developers! If you are appearing for any front-end profile interview, these basic task-based 60 questions, and 40 advance questions along with code snippets as answers, provide a practical and efficient way to learn JavaScript. This collection is designed to help you not only understand JavaScript fundamentals but also build the logical and problem-solving skills crucial for tackling real-world challenges in front-end development.
From manipulating the DOM and handling events to working with arrays, objects, and modern ES6+ features, these tasks cover a comprehensive range of topics. Whether you're refreshing your skills or preparing for technical rounds, this structured approach ensures you’re ready to demonstrate your proficiency in JavaScript.
So, gear up, practice diligently, and let these exercises guide you toward acing your interviews and excelling as a front-end developer!
Basic task-based 60 questions
1. Variable Declaration
Q: What is the difference between var
, let
, and const
? Write a code example showing their scope differences.
A:
function testScope() {
if (true) {
var a = "I am var";
let b = "I am let";
const c = "I am const";
}
console.log(a); // Accessible
console.log(b); // Error
console.log(c); // Error
}
testScope();
2. Hoisting
Q: Explain hoisting in JavaScript with an example.
A:
console.log(a); // undefined (hoisted)
var a = 10;
console.log(b); // Error (not hoisted)
let b = 20;
3. Closures
Q: Write a function to demonstrate closures in JavaScript.
A:
function outerFunction() {
let counter = 0;
return function innerFunction() {
counter++;
return counter;
};
}
const increment = outerFunction();
console.log(increment()); // 1
console.log(increment()); // 2
4. Event Loop
Q: Explain the event loop with an example using setTimeout
and Promise
.
A:
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));
console.log("End");
// Output: Start, End, Promise, Timeout
5. Prototypal Inheritance
Q: How does inheritance work in JavaScript?
A:
function Parent() {
this.name = "Parent";
}
Parent.prototype.greet = function () {
console.log("Hello from " + this.name);
};
function Child() {
Parent.call(this);
this.name = "Child";
}
Child.prototype = Object.create(Parent.prototype);
const child = new Child();
child.greet(); // Hello from Child
6. Callback Functions
Q: Write a function using a callback.
A:
function greet(name, callback) {
console.log("Hi " + name);
callback();
}
greet("Joe", () => {
console.log("Callback executed!");
});
7. Promises
Q: Create a Promise that resolves after 2 seconds.
A:
const promise = new Promise((resolve) => {
setTimeout(() => resolve("Resolved!"), 2000);
});
promise.then((msg) => console.log(msg));
8. Async/Await
Q: Write an async
function that fetches data.
A:
async function fetchData() {
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
const data = await response.json();
console.log(data);
}
fetchData();
9. Array Methods
Q: Write a code snippet using map
, filter
, and reduce
.
A:
const numbers = [1, 2, 3, 4];
const doubled = numbers.map((n) => n * 2);
const even = numbers.filter((n) => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(doubled, even, sum);
10. Destructuring
Q: Use destructuring to extract values from an array and object.
A:
const arr = [1, 2, 3];
const [a, b] = arr;
const obj = { x: 10, y: 20 };
const { x, y } = obj;
console.log(a, b, x, y); // 1, 2, 10, 20
11. Rest and Spread Operators
Q: Write a function using rest and spread operators.
A:
function sum(...nums) {
return nums.reduce((acc, n) => acc + n, 0);
}
console.log(sum(1, 2, 3)); // 6
const arr1 = [1, 2];
const arr2 = [3, 4];
console.log([...arr1, ...arr2]); // [1, 2, 3, 4]
12. ES6 Classes
Q: Create a class in JavaScript with a constructor and method.
A:
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
const person = new Person("Joe");
person.greet();
13. Debouncing
Q: Write a debouncing function.
A:
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => func(...args), delay);
};
}
const log = debounce(() => console.log("Debounced!"), 1000);
log();
14. Throttling
Q: Write a throttling function.
A:
function throttle(func, limit) {
let inThrottle;
return function (...args) {
if (!inThrottle) {
func(...args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
const log = throttle(() => console.log("Throttled!"), 1000);
log();
15. Default Parameters
Q: Demonstrate the use of default parameters in JavaScript.
A:
function greet(name = "Guest") {
console.log(`Hello, ${name}`);
}
greet(); // Hello, Guest
greet("Joe"); // Hello, Joe
16. Template Literals
Q: Write a function that uses template literals.
A:
function describePerson(name, age) {
console.log(`My name is ${name} and I am ${age} years old.`);
}
describePerson("Joe", 25);
17. Object Methods
Q: Demonstrate Object.keys
, Object.values
, and Object.entries
.
A:
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj)); // ['a', 'b', 'c']
console.log(Object.values(obj)); // [1, 2, 3]
console.log(Object.entries(obj)); // [['a', 1], ['b', 2], ['c', 3]]
18. Optional Chaining
Q: Use optional chaining to safely access properties.
A:
const user = { name: "Joe", address: { city: "New York" } };
console.log(user?.address?.city); // New York
console.log(user?.contact?.phone); // undefined
19. Nullish Coalescing Operator
Q: Use the nullish coalescing operator (??
).
A:
const name = null;
const defaultName = name ?? "Guest";
console.log(defaultName); // Guest
20. Spread with Objects
Q: Merge two objects using the spread operator.
A:
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 3, c: 4 }
21. Symbol
Q: Create a symbol and use it as an object property.
A:
const sym = Symbol("unique");
const obj = { [sym]: "value" };
console.log(obj[sym]); // value
22. Iterators
Q: Write an iterator for a custom object.
A:
const iterable = {
data: [1, 2, 3],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.data.length) {
return { value: this.data[index++], done: false };
}
return { done: true };
},
};
},
};
for (const value of iterable) {
console.log(value);
}
23. Generators
Q: Create a generator function.
A:
function* generatorFunc() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunc();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
24. Set
Q: Demonstrate Set
operations in JavaScript.
A:
const set = new Set([1, 2, 3, 1]);
set.add(4);
set.delete(2);
console.log(set.has(1)); // true
console.log([...set]); // [1, 3, 4]
25. Map
Q: Demonstrate Map
operations in JavaScript.
A:
const map = new Map();
map.set("a", 1);
map.set("b", 2);
console.log(map.get("a")); // 1
map.delete("b");
console.log(map.has("b")); // false
26. WeakMap and WeakSet
Q: Explain WeakMap
and WeakSet
with examples.
A:
let obj = { key: "value" };
const weakMap = new WeakMap();
weakMap.set(obj, "WeakMap value");
console.log(weakMap.get(obj)); // WeakMap value
obj = null; // Object removed from memory
const weakSet = new WeakSet();
weakSet.add(obj); // Error if obj is null
27. This Keyword
Q: Demonstrate this
keyword in different contexts.
A:
const obj = {
name: "Joe",
greet() {
console.log(this.name);
},
};
obj.greet(); // Joe
function globalGreet() {
console.log(this); // Window (in browsers)
}
globalGreet();
28. Arrow Functions
Q: How do arrow functions differ from regular functions?
A:
const regularFunc = function () {
console.log(this); // Dynamic (depends on call site)
};
const arrowFunc = () => {
console.log(this); // Lexical (inherits from parent scope)
};
regularFunc();
arrowFunc();
29. Function Currying
Q: Implement function currying in JavaScript.
A:
function multiply(a) {
return (b) => a * b;
}
const double = multiply(2);
console.log(double(5)); // 10
30. Event Delegation
Q: Explain event delegation with a code example.
A:
document.querySelector("#parent").addEventListener("click", (e) => {
if (e.target && e.target.matches("button.child")) {
console.log("Child button clicked");
}
});
31. Deep and Shallow Copy
Q: Explain the difference between deep and shallow copy with examples.
A:
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
shallowCopy.b.c = 5; // Affects the original object
console.log(obj.b.c); // 5
const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 10; // Does not affect the original object
console.log(obj.b.c); // 5
32. JSON Methods
Q: Demonstrate JSON.stringify
and JSON.parse
.
A:
const obj = { name: "Joe", age: 25 };
const jsonString = JSON.stringify(obj);
console.log(jsonString); // '{"name":"Joe","age":25}'
const parsedObj = JSON.parse(jsonString);
console.log(parsedObj); // { name: "Joe", age: 25 }
33. Module System
Q: Explain import
and export
in JavaScript modules.
A:
// math.js
export const add = (a, b) => a + b;
// main.js
import { add } from "./math.js";
console.log(add(2, 3)); // 5
34. Web Storage API
Q: Use localStorage
and sessionStorage
.
A:
localStorage.setItem("name", "Joe");
console.log(localStorage.getItem("name")); // Joe
sessionStorage.setItem("age", "25");
console.log(sessionStorage.getItem("age")); // 25
35. Fetch API with Error Handling
Q: Perform a GET
request and handle errors.
A:
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => {
if (!response.ok) throw new Error("Network error");
return response.json();
})
.then((data) => console.log(data))
.catch((error) => console.error(error));
36. Async/Await with Error Handling
Q: Handle errors using try-catch
with async/await
.
A:
async function fetchData() {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
if (!response.ok) throw new Error("Network error");
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
fetchData();
37. DOM Manipulation
Q: Add a new element to the DOM dynamically.
A:
const newDiv = document.createElement("div");
newDiv.textContent = "Hello, DOM!";
document.body.appendChild(newDiv);
38. Event Listeners
Q: Attach an event listener to a button.
A:
const button = document.querySelector("#myButton");
button.addEventListener("click", () => {
console.log("Button clicked!");
});
39. Prevent Default Behavior
Q: Demonstrate how to prevent default behavior of a form submission.
A:
document.querySelector("form").addEventListener("submit", (e) => {
e.preventDefault();
console.log("Form submission prevented!");
});
40. Bubbling and Capturing
Q: Explain event bubbling and capturing with an example.
A:
document.querySelector("#parent").addEventListener(
"click",
() => console.log("Parent clicked!"),
true // Use capturing phase
);
document.querySelector("#child").addEventListener("click", () => {
console.log("Child clicked!");
});
41. Custom Events
Q: Create and dispatch a custom event.
A:
const event = new CustomEvent("myEvent", { detail: { message: "Hello!" } });
document.addEventListener("myEvent", (e) => {
console.log(e.detail.message);
});
document.dispatchEvent(event);
42. Date and Time
Q: Get the current date and format it.
A:
const now = new Date();
console.log(now.toISOString()); // Current date in ISO format
console.log(now.toLocaleDateString()); // Local date format
43. Regular Expressions
Q: Validate an email address using regex.
A:
const email = "example@example.com";
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
console.log(isValid); // true
44. Error Handling
Q: Use try-catch
for error handling.
A:
try {
JSON.parse("{ malformed: json }");
} catch (error) {
console.error("Error parsing JSON:", error.message);
}
45. Constructor Functions
Q: Create an object using a constructor function.
A:
function Person(name, age) {
this.name = name;
this.age = age;
}
const joe = new Person("Joe", 25);
console.log(joe.name); // Joe
46. ES6 Set Timeout/Interval
Q: Use setTimeout
and setInterval
.
A:
setTimeout(() => console.log("Timeout executed!"), 1000);
const interval = setInterval(() => console.log("Interval executed!"), 1000);
setTimeout(() => clearInterval(interval), 5000);
47. Call, Apply, and Bind
Q: Demonstrate call
, apply
, and bind
.
A:
const obj = { name: "Joe" };
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
greet.call(obj, "Hello");
greet.apply(obj, ["Hi"]);
const boundGreet = greet.bind(obj, "Hey");
boundGreet();
48. Polyfills
Q: Create a polyfill for Array.prototype.map
.
A:
Array.prototype.myMap = function (callback) {
const result = [];
for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i, this));
}
return result;
};
console.log([1, 2, 3].myMap((n) => n * 2)); // [2, 4, 6]
49. Object Freezing
Q: Demonstrate Object.freeze
.
A:
const obj = { a: 1 };
Object.freeze(obj);
obj.a = 2; // No effect
console.log(obj.a); // 1
50. Promises in Sequence
Q: Execute promises in sequence.
A:
const promises = [1, 2, 3].map(
(num) => new Promise((resolve) => setTimeout(() => resolve(num), 1000))
);
promises.reduce((acc, curr) => acc.then(() => curr.then(console.log)), Promise.resolve());
51. Throttling
Q: Implement a throttling function in JavaScript.
A:
function throttle(func, delay) {
let lastCall = 0;
return function (...args) {
const now = new Date().getTime();
if (now - lastCall >= delay) {
lastCall = now;
func(...args);
}
};
}
const log = throttle(() => console.log("Throttled!"), 2000);
window.addEventListener("resize", log);
52. Debouncing
Q: Implement a debouncing function in JavaScript.
A:
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => func(...args), delay);
};
}
const log = debounce(() => console.log("Debounced!"), 2000);
window.addEventListener("resize", log);
53. Function Composition
Q: Create a function composition utility.
A:
const compose = (...functions) => (value) =>
functions.reduceRight((acc, func) => func(acc), value);
const add = (x) => x + 1;
const double = (x) => x * 2;
const composedFunc = compose(add, double);
console.log(composedFunc(5)); // (5 * 2) + 1 = 11
54. Hoisting
Q: Explain hoisting with examples.
A:
console.log(a); // undefined (var hoisted, but not initialized)
var a = 10;
console.log(b); // ReferenceError (let and const are not hoisted in the same way)
let b = 20;
greet(); // Function hoisted
function greet() {
console.log("Hello!");
}
55. Closures
Q: Create a closure and explain how it works.
A:
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
};
}
const increment = outer();
increment(); // 1
increment(); // 2
56. Promises with All, AllSettled, Race, and Any
Q: Demonstrate Promise.all
, Promise.allSettled
, Promise.race
, and Promise.any
.
A:
const promises = [
Promise.resolve(1),
Promise.reject("Error"),
Promise.resolve(3),
];
Promise.all(promises)
.then(console.log)
.catch(console.error); // Error
Promise.allSettled(promises).then(console.log);
// [{status: 'fulfilled', value: 1}, {status: 'rejected', reason: 'Error'}, {status: 'fulfilled', value: 3}]
Promise.race(promises).then(console.log).catch(console.error); // 1
Promise.any(promises).then(console.log).catch(console.error); // 1 (ignores rejections)
57. Event Loop
Q: Explain the event loop with an example.
A:
console.log("Start");
setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));
console.log("End");
// Output: Start, End, Promise, Timeout
58. Callbacks
Q: Write a function that uses a callback.
A:
function fetchData(callback) {
setTimeout(() => {
callback("Data fetched");
}, 1000);
}
fetchData((data) => console.log(data)); // Data fetched
59. Strict Mode
Q: Explain the purpose of "use strict"
with examples.
A:
"use strict";
x = 10; // ReferenceError: x is not defined
console.log(x);
60. Asynchronous Iteration
Q: Use for-await-of
to handle asynchronous iteration.
A:
const asyncIterable = {
async *[Symbol.asyncIterator]() {
yield "Hello";
yield "Async";
yield "Iteration";
},
};
(async () => {
for await (const word of asyncIterable) {
console.log(word);
}
})();
// Output: Hello, Async, Iteration
Advanced JavaScript Questions and Answers
1. What is Currying? Implement it.
A: Currying is the process of transforming a function with multiple arguments into a sequence of functions, each taking a single argument.
function curry(func) {
return function curried(...args) {
if (args.length >= func.length) {
return func(...args);
} else {
return (...nextArgs) => curried(...args, ...nextArgs);
}
};
}
function sum(a, b, c) {
return a + b + c;
}
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
2. What is Memoization? Implement a memoized function.
A: Memoization is an optimization technique where function results are cached to avoid redundant computations.
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(...args);
cache.set(key, result);
return result;
};
}
const fib = memoize((n) => (n <= 1 ? n : fib(n - 1) + fib(n - 2)));
console.log(fib(10)); // 55
3. Explain Prototypal Inheritance with an Example.
A: In JavaScript, objects can inherit from other objects via prototypes.
const person = {
greet() {
console.log(`Hello, my name is ${this.name}`);
},
};
const joe = Object.create(person);
joe.name = "Joe";
joe.greet(); // Hello, my name is Joe
4. Implement a Custom Promise.all
Method.
A:
function customPromiseAll(promises) {
return new Promise((resolve, reject) => {
const results = [];
let completed = 0;
promises.forEach((promise, index) => {
Promise.resolve(promise)
.then((value) => {
results[index] = value;
completed += 1;
if (completed === promises.length) resolve(results);
})
.catch(reject);
});
});
}
const promises = [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)];
customPromiseAll(promises).then(console.log); // [1, 2, 3]
5. Implement a Singleton Pattern.
A:
const Singleton = (function () {
let instance;
return function () {
if (!instance) {
instance = this;
}
return instance;
};
})();
const obj1 = new Singleton();
const obj2 = new Singleton();
console.log(obj1 === obj2); // true
6. What are WeakMap and WeakSet? Use Cases.
A: WeakMap
and WeakSet
allow for garbage collection of their keys when no other references exist.
let obj = { key: "value" };
const weakMap = new WeakMap();
weakMap.set(obj, "metadata");
obj = null; // The object is garbage-collected
console.log(weakMap); // WeakMap { <items unknown> }
7. Explain Debounce and Implement It Using Promises.
A: Debounce ensures a function is executed only after a specified delay since its last call.
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => func(...args), delay);
};
}
const log = debounce((msg) => console.log(msg), 1000);
log("Hello"); // Executed only after 1 second if no other calls occur
8. What is a Proxy? Implement a Logging Proxy.
A: A Proxy
is used to define custom behavior for fundamental operations.
const handler = {
get(target, prop) {
console.log(`Accessing ${prop}`);
return target[prop];
},
set(target, prop, value) {
console.log(`Setting ${prop} to ${value}`);
target[prop] = value;
return true;
},
};
const obj = new Proxy({ a: 1 }, handler);
console.log(obj.a); // Accessing a
obj.b = 2; // Setting b to 2
9. Explain Tail Call Optimization with an Example.
A: Tail call optimization occurs when a function makes a call as its last action, allowing stack reuse.
function factorial(n, acc = 1) {
if (n === 0) return acc;
return factorial(n - 1, acc * n); // Tail call
}
console.log(factorial(5)); // 120
10. Implement an Event Emitter.
A:
class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(listener);
}
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach((listener) => listener(...args));
}
}
}
const emitter = new EventEmitter();
emitter.on("sayHello", (name) => console.log(`Hello, ${name}`));
emitter.emit("sayHello", "Joe"); // Hello, Joe
11. Explain and Implement Generators.
A: Generators produce a sequence of values using the yield
keyword.
function* generateSequence() {
yield 1;
yield 2;
yield 3;
}
const generator = generateSequence();
console.log(generator.next().value); // 1
console.log(generator.next().value); // 2
console.log(generator.next().value); // 3
12. What are Iterators? Implement a Custom Iterator.
A: Iterators are objects that allow sequential access to their elements.
const customIterable = {
data: [1, 2, 3],
[Symbol.iterator]() {
let index = 0;
const data = this.data;
return {
next() {
if (index < data.length) {
return { value: data[index++], done: false };
}
return { value: undefined, done: true };
},
};
},
};
for (const item of customIterable) {
console.log(item); // 1, 2, 3
}
13. Implement a Deep Clone Function.
A:
function deepClone(obj) {
if (obj === null || typeof obj !== "object") return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof Array) return obj.map(deepClone);
if (obj instanceof Object) {
return Object.keys(obj).reduce((acc, key) => {
acc[key] = deepClone(obj[key]);
return acc;
}, {});
}
}
const original = { a: 1, b: { c: 2 }, d: [3, 4] };
const clone = deepClone(original);
console.log(clone); // { a: 1, b: { c: 2 }, d: [3, 4] }
14. Explain the Difference Between Call, Apply, and Bind.
A:
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
const person = { name: "Joe" };
greet.call(person, "Hello", "!"); // Hello, Joe!
greet.apply(person, ["Hi", "?"]); // Hi, Joe?
const boundGreet = greet.bind(person, "Hey");
boundGreet("!"); // Hey, Joe!
15. What is a Symbol? Use Case.
A: Symbol
is a unique and immutable data type primarily used as object keys.
const id = Symbol("id");
const user = {
name: "Joe",
[id]: 123,
};
console.log(user[id]); // 123
console.log(Object.keys(user)); // ["name"] (id is not enumerable)
16. Implement a Rate Limiter Using Closures.
A:
function rateLimiter(func, limit, interval) {
let calls = 0;
const queue = [];
const execute = () => {
if (queue.length === 0 || calls >= limit) return;
calls++;
queue.shift()();
setTimeout(() => {
calls--;
execute();
}, interval);
};
return (...args) => {
queue.push(() => func(...args));
execute();
};
}
const limitedFunc = rateLimiter(() => console.log("Executed"), 2, 1000);
limitedFunc(); // Executed
limitedFunc(); // Executed
limitedFunc(); // Delayed
17. Explain Async/Await Error Handling with Examples.
A:
async function fetchData() {
try {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
console.log(data);
} catch (error) {
console.error("Error:", error);
}
}
fetchData();
18. What is Object.freeze
? Demonstrate Its Use.
A: Object.freeze
makes an object immutable.
const obj = { a: 1 };
Object.freeze(obj);
obj.a = 2; // No effect
console.log(obj.a); // 1
19. Implement a Custom Map Function.
A:
Array.prototype.customMap = function (callback) {
const result = [];
for (let i = 0; i < this.length; i++) {
result.push(callback(this[i], i, this));
}
return result;
};
const arr = [1, 2, 3];
console.log(arr.customMap((x) => x * 2)); // [2, 4, 6]
20. Explain Event Delegation with an Example.
A:
document.getElementById("parent").addEventListener("click", (event) => {
if (event.target.tagName === "BUTTON") {
console.log(`Button clicked: ${event.target.textContent}`);
}
});
// Dynamically added buttons will also trigger the handler.
21. Implement a Retry Mechanism for Failed Promises.
A:
async function retry(func, retries = 3) {
while (retries > 0) {
try {
return await func();
} catch (error) {
retries--;
if (retries === 0) throw error;
}
}
}
retry(() => fetch("https://api.example.com"), 3)
.then(console.log)
.catch(console.error);
22. What Are Mixins? Implement One.
A: Mixins allow objects to share functionality.
const sayHiMixin = {
sayHi() {
console.log(`Hi, ${this.name}`);
},
};
class User {
constructor(name) {
this.name = name;
}
}
Object.assign(User.prototype, sayHiMixin);
const user = new User("Joe");
user.sayHi(); // Hi, Joe
23. Implement a Custom Reduce Function.
A:
Array.prototype.customReduce = function (callback, initialValue) {
let acc = initialValue === undefined ? this[0] : initialValue;
let startIndex = initialValue === undefined ? 1 : 0;
for (let i = startIndex; i < this.length; i++) {
acc = callback(acc, this[i], i, this);
}
return acc;
};
const arr = [1, 2, 3];
console.log(arr.customReduce((sum, num) => sum + num, 0)); // 6
24. Explain the Module Pattern.
A:
const counterModule = (function () {
let count = 0;
return {
increment() {
count++;
},
getCount() {
return count;
},
};
})();
counterModule.increment();
console.log(counterModule.getCount()); // 1
25. Implement a Custom Event Bus.
A: An Event Bus is a pattern for managing communication between different parts of an application.
class EventBus {
constructor() {
this.events = {};
}
subscribe(event, callback) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(callback);
}
publish(event, ...args) {
if (this.events[event]) {
this.events[event].forEach((callback) => callback(...args));
}
}
unsubscribe(event, callback) {
if (this.events[event]) {
this.events[event] = this.events[event].filter((cb) => cb !== callback);
}
}
}
const bus = new EventBus();
const onEvent = (data) => console.log(`Event received with data: ${data}`);
bus.subscribe("testEvent", onEvent);
bus.publish("testEvent", "Hello!"); // Event received with data: Hello!
bus.unsubscribe("testEvent", onEvent);
bus.publish("testEvent", "Hello again!"); // No output
26. Explain and Implement Throttling.
A: Throttling ensures a function is executed at most once in a specified time frame.
function throttle(func, delay) {
let lastCall = 0;
return function (...args) {
const now = Date.now();
if (now - lastCall >= delay) {
lastCall = now;
func(...args);
}
};
}
const log = throttle((msg) => console.log(msg), 1000);
log("Hello"); // Executed immediately
log("World"); // Ignored if called within 1 second
27. Explain Reflect
and Its Use Cases.
A: The Reflect
API provides methods for interceptable JavaScript operations.
const user = {};
Reflect.set(user, "name", "Joe");
console.log(Reflect.get(user, "name")); // Joe
console.log(Reflect.has(user, "name")); // true
28. What is the Difference Between ==
and ===
?
A:
==
checks for equality after type coercion.===
checks for strict equality without type coercion.
console.log(5 == "5"); // true (type coercion)
console.log(5 === "5"); // false (strict equality)
29. Implement a Custom Promise.race
Method.
A:
function customPromiseRace(promises) {
return new Promise((resolve, reject) => {
promises.forEach((promise) => {
Promise.resolve(promise).then(resolve).catch(reject);
});
});
}
const p1 = new Promise((res) => setTimeout(res, 500, "First"));
const p2 = new Promise((res) => setTimeout(res, 300, "Second"));
customPromiseRace([p1, p2]).then(console.log); // Second
30. Explain the Observer Pattern. Implement It.
A: The Observer Pattern allows objects (observers) to watch and react to changes in another object (subject).
class Subject {
constructor() {
this.observers = [];
}
addObserver(observer) {
this.observers.push(observer);
}
removeObserver(observer) {
this.observers = this.observers.filter((obs) => obs !== observer);
}
notify(data) {
this.observers.forEach((observer) => observer.update(data));
}
}
class Observer {
update(data) {
console.log(`Observer received data: ${data}`);
}
}
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notify("Hello Observers!"); // Both observers receive the update
31. Explain Set
and Map
. When Should You Use Them?
A:
Set
: A collection of unique values.Map
: A collection of key-value pairs.
const set = new Set([1, 2, 2, 3]);
console.log(set); // Set { 1, 2, 3 }
const map = new Map();
map.set("name", "Joe");
console.log(map.get("name")); // Joe
32. What Are Optional Chaining and Nullish Coalescing?
A:
Optional Chaining (
?.
) prevents errors when accessing properties ofnull
orundefined
.Nullish Coalescing (
??
) provides a default value when a value isnull
orundefined
.
const user = { name: "Joe" };
console.log(user?.address?.city); // undefined (safe access)
const value = null;
console.log(value ?? "default"); // "default"
33. Implement a Custom Flatten Function for Nested Arrays.
A:
function flatten(arr) {
return arr.reduce(
(acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val),
[]
);
}
const nested = [1, [2, [3, 4]], 5];
console.log(flatten(nested)); // [1, 2, 3, 4, 5]
34. What Are Tagged Templates?
A: Tagged templates process template literals with a custom function.
function tag(strings, ...values) {
return strings.reduce(
(result, str, i) => `${result}${str}${values[i] || ""}`,
""
);
}
const name = "Joe";
console.log(tag`Hello, ${name}!`); // Hello, Joe!
35. Explain Object.create
and Its Use Cases.
A: Object.create
creates a new object with the specified prototype.
const parent = { greet() { console.log("Hello"); } };
const child = Object.create(parent);
child.greet(); // Hello
36. What Are Generators in JavaScript?
A: Generators allow functions to yield multiple values over time.
function* counter() {
yield 1;
yield 2;
yield 3;
}
const gen = counter();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
37. What Is the Purpose of Symbol.iterator
?
A: It customizes the iteration behavior of objects.
const iterable = {
[Symbol.iterator]() {
let i = 0;
return {
next() {
return i < 3 ? { value: i++, done: false } : { done: true };
},
};
},
};
for (const val of iterable) {
console.log(val); // 0, 1, 2
}
38. What Is Hoisting?
A: Hoisting moves variable and function declarations to the top of their scope.
console.log(a); // undefined (hoisted declaration)
var a = 5;
39. What Are JavaScript Modules?
A: Modules enable code reuse and better organization.
// math.js
export function add(a, b) { return a + b; }
// main.js
import { add } from "./math.js";
console.log(add(2, 3)); // 5
40. What Is the Purpose of Object.seal
?
A: Object.seal
prevents adding or removing properties from an object.
const obj = { a: 1 };
Object.seal(obj);
obj.b = 2; // Not allowed
console.log(obj); // { a: 1 }
Conclusion
The above 100 code snippets, coupled with consistent practice and revision, can significantly improve your logical understanding and problem-solving skills in JavaScript. By focusing on real-world tasks and exploring diverse scenarios, you can develop a strong foundation in the language's core concepts and advanced features.
JavaScript’s ability to handle everything from simple interactions to complex applications makes it an essential skill for any developer. Each snippet serves as a stepping stone, helping you gain confidence in areas like DOM manipulation, asynchronous programming, ES6+ features, and more.
Remember, mastery comes with persistence. Keep experimenting, revisiting concepts, and building on what you’ve learned. With dedication, you’ll not only enhance your JavaScript skills but also unlock the potential to create dynamic, robust, and scalable applications.