Mastering Frontend Concepts: A Guide to Top Interview Questions

Adarsh Somani
3 min readJan 6, 2025

--

Photo by Ferenc Almasi on Unsplash

Introduction

Frontend interviews often include JavaScript challenges to evaluate problem-solving skills, deep understanding of core concepts, and ability to write maintainable code. This guide covers frequently asked questions from top tech companies like Flipkart, Meta, Google, Amazon, and others.

Topics Covered

1. Debouncing

Debouncing ensures a function is executed only after a specified delay has passed since the last time it was invoked.

function debounce(func, wait) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
// Example Usage:
const log = debounce(() => console.log("Debounced!"), 300);
log(); // Executes after 300ms if no new calls

2. Throttling

Throttling ensures a function is executed at most once in a given time interval.

function throttle(func, wait) {
let lastCall = 0;
return function (...args) {
const now = Date.now();
if (now - lastCall >= wait) {
lastCall = now;
func.apply(this, args);
}
};
}
// Example Usage:
const log = throttle(() => console.log("Throttled!"), 1000);
log(); // Executes immediately, ignores further calls within 1 second

3. Currying

Currying transforms a function into a sequence of functions, each taking a single argument.

function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn(...args);
}
return (...nextArgs) => curried(...args, ...nextArgs);
};
}
// Example Usage:
const add = (a, b, c) => a + b + c;
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // Output: 6

4. Custom Promises

Implementing a basic Promise-like structure.

class CustomPromise {
constructor(executor) {
this.state = "pending";
this.value = undefined;
this.callbacks = [];
    const resolve = (value) => {
if (this.state === "pending") {
this.state = "fulfilled";
this.value = value;
this.callbacks.forEach((cb) => cb());
}
};
executor(resolve);
}
then(onFulfilled) {
return new CustomPromise((resolve) => {
const handle = () => {
const result = onFulfilled(this.value);
resolve(result);
};
if (this.state === "fulfilled") {
handle();
} else {
this.callbacks.push(handle);
}
});
}
}
// Example Usage:
new CustomPromise((resolve) => resolve(42))
.then((value) => value + 1)
.then(console.log); // Output: 43

5. Deep Flatten

Flattening a nested array up to a given depth.

function deepFlatten(arr, depth = Infinity) {
return depth > 0
? arr.reduce((flat, item) =>
flat.concat(Array.isArray(item) ? deepFlatten(item, depth - 1) : item), []
)
: arr.slice();
}
// Example Usage:
const nested = [1, [2, [3, [4, [5]]]]];
console.log(deepFlatten(nested, 4)); // Output: [1, 2, 3, 4, [5]]

6. Custom JSON.stringify

A custom implementation of JSON.stringify.

function customStringify(obj) {
if (typeof obj !== "object" || obj === null) return String(obj);
if (Array.isArray(obj)) return `[${obj.map(customStringify).join(",")}]`;
return `{${Object.entries(obj)
.map(([key, value]) => `"${key}":${customStringify(value)}`)
.join(",")}}`;
}
// Example Usage:
const obj = { a: 1, b: { c: 2 } };
console.log(customStringify(obj)); // Output: {"a":1,"b":{"c":2}}

7. Event Emitter

A basic event emitter implementation.

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));
}
}
off(event, listener) {
if (!this.events[event]) return;
this.events[event] = this.events[event].filter((l) => l !== listener);
}
}
// Example Usage:
const emitter = new EventEmitter();
emitter.on("log", (msg) => console.log(msg));
emitter.emit("log", "Hello World!"); // Output: Hello World!

8. Lodash _.get

A simplified version of Lodash’s get function.

function get(obj, path, defaultValue) {
return path.split(".").reduce((acc, key) => acc?.[key], obj) || defaultValue;
}
// Example Usage:
const data = { a: { b: { c: 42 } } };
console.log(get(data, "a.b.c", "default")); // Output: 42
console.log(get(data, "a.x.c", "default")); // Output: "default"

9. Deep Clone

A deep cloning function for objects.

function deepClone(obj) {
if (obj === null || typeof obj !== "object") return obj;
if (Array.isArray(obj)) return obj.map(deepClone);
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => [key, deepClone(value)])
);
}
// Example Usage:
const obj = { a: { b: 2 }, c: [1, 2] };
const clone = deepClone(obj);
console.log(clone); // Output: { a: { b: 2 }, c: [1, 2] }

Summary

This guide addresses the most common frontend interview questions, consolidating concepts like debouncing, throttling, currying, and custom implementations of Promises, JSON.stringify, and more. By mastering these implementations, you’ll not only prepare for interviews but also gain a stronger understanding of JavaScript fundamentals.

--

--

No responses yet