JavaScript Interview Questions - Functions & Patterns
25 interview questions on higher-order functions, currying, function composition, IIFE, memoization, debouncing, throttling, and design patterns.
25 interview questions on higher-order functions, currying, function composition, IIFE, memoization, debouncing, throttling, and design patterns. This interview-focused guide covers essential javascript interview questions - functions & patterns concepts for technical interviews.
JavaScript Interview Questions – Functions & Patterns
Functions are first-class citizens in JavaScript. These 25 questions cover higher-order functions, currying, memoization, debouncing, throttling, IIFE, recursion, and common function design patterns.
1. What are higher-order functions?
A higher-order function takes a function as an argument or returns a function.
// Takes a function
[1, 2, 3].map(n => n * 2);
[1, 2, 3, 4].filter(n => n % 2 === 0);
// Returns a function
function multiplyBy(factor) {
return number => number * factor;
}
const double = multiplyBy(2);
2. What is currying?
Transforms a function with multiple arguments into a sequence of unary functions.
// Normal: add(a, b, c)
// Curried: add(a)(b)(c)
const add = a => b => c => a + b + c;
console.log(add(1)(2)(3)); // 6
[!TIP] Currying is used extensively in functional programming and libraries like Redux middleware, Ramda, and Lodash/fp.
3. What is memoization?
Caches function results based on arguments to avoid redundant computations.
function memoize(fn) {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (!cache.has(key)) cache.set(key, fn(...args));
return cache.get(key);
};
}
const fib = memoize(n => n <= 1 ? n : fib(n - 1) + fib(n - 2));
4. What is debouncing?
Ensures a function is only called after a specified delay since the last invocation. Used for search inputs, window resize handlers.
function debounce(fn, delay = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
[!IMPORTANT] Debounce: Wait until user stops. Throttle: Execute at most once per interval. Use debounce for search, throttle for scroll.
5. What is throttling?
Ensures a function is called at most once in a specified time period.
function throttle(fn, limit = 200) {
let inThrottle = false;
return (...args) => {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
6. What is an IIFE?
An Immediately Invoked Function Expression runs as soon as it's defined. Creates a private scope.
// Classic IIFE
(function() {
const privateVar = "I'm private";
})();
// Module pattern with IIFE
const counter = (() => {
let count = 0;
return { increment: () => ++count, decrement: () => --count };
})();
7. What is function composition?
Combines functions where the output of one becomes the input of the next (right-to-left).
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const addOne = x => x + 1;
const double = x => x * 2;
const transform = compose(double, addOne); // double(addOne(x))
console.log(transform(3)); // 8
8. What is the difference between call, apply, and bind?
call(thisArg, arg1, arg2)— invokes immediately with individual argsapply(thisArg, [args])— invokes immediately with array argbind(thisArg, arg1, ...)— returns a new bound function (delayed execution)
function greet(g, p) { return `${g}, ${this.name}${p}`; }
const user = { name: "Alice" };
greet.call(user, "Hello", "!"); // "Hello, Alice!"
greet.apply(user, ["Hi", "?"]); // "Hi, Alice?"
const bound = greet.bind(user, "Hey");
bound("!!"); // "Hey, Alice!!"
9. What is the difference between Function Declaration and Function Expression?
- Declaration:
function foo() {}— hoisted, can be called before definition - Expression:
const foo = function() {}— not hoisted, TDZ with let/const
10. What is recursion?
A function that calls itself. Requires a base case to terminate.
function factorial(n) {
if (n <= 1) return 1; // Base case
return n * factorial(n - 1); // Recursive case
}
11. What is a pure function?
A function that (1) always returns the same output for the same input and (2) has no side effects (no modifying external state, no I/O).
// Pure
const add = (a, b) => a + b;
// Impure
let total = 0;
const addToTotal = (n) => { total += n; return total; };
12. What are side effects?
Operations that modify state outside the function scope: DOM manipulation, API calls, console.log, modifying global variables, writing to files, mutating arguments.
13. What is a callback function?
A function passed as an argument to another function, invoked later (synchronously or asynchronously).
// Synchronous callback
[1, 2, 3].forEach(x => console.log(x));
// Asynchronous callback
setTimeout(() => console.log("Done"), 1000);
14. What is "callback hell" and how to avoid it?
Deeply nested callbacks that create hard-to-read pyramid code. Solutions: Promises (.then() chaining), async/await.
15. What is a generator function?
A function (function*) that can pause execution and resume later using yield.
function* idGen() {
let id = 1;
while (true) yield id++;
}
16. What is a factory function?
A function that returns a new object without using new.
function createUser(name, email) {
return {
name, email,
greet() { return `Hi, I'm ${this.name}`; }
};
}
[!TIP] Factory functions are an alternative to classes — they don't have
thisbinding issues and work well with closures for private data.
17. What is the constructor pattern?
Uses new with a function to create objects. Sets up prototype chain automatically.
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() { return `Hi, ${this.name}`; };
const alice = new Person("Alice");
18. What is the module pattern?
Uses closures to create private variables and expose a public API.
const Database = (() => {
const data = [];
return {
add(item) { data.push(item); },
getAll() { return [...data]; }
};
})();
19. What is the revealing module pattern?
A variation of the module pattern that defines all functions privately and exposes only selected ones.
20. What is the singleton pattern?
Ensures a class has only one instance and provides a global access point.
const Singleton = (() => {
let instance;
function create() { return { data: [] }; }
return { getInstance: () => instance ||= create() };
})();
21. What is the observer (pub/sub) pattern?
Objects (observers) subscribe to events from another object (subject). When state changes, all observers are notified.
class EventEmitter {
constructor() { this.events = {}; }
on(event, fn) { (this.events[event] ||= []).push(fn); }
emit(event, data) { this.events[event]?.forEach(fn => fn(data)); }
}
22. What are arrow function limitations?
- No own
this(lexical only) - No
argumentsobject - Cannot be constructors
- No
prototypeproperty - Cannot be generators
- Cannot use
yield(unless inside a generator)
23. What is the difference between parameters and arguments?
- Parameters: Variables listed in function definition
- Arguments: Actual values passed when calling the function
24. What is a method?
A function that is a property of an object.
const obj = {
greet() { return "Hello"; } // Method
};
25. What is eval() and why is it dangerous?
Executes a string as JavaScript code. Security risk (code injection), prevents engine optimizations, and has performance issues.
[!CAUTION] Never use
eval()in production. It's one of the most dangerous functions in JavaScript. UseJSON.parse()for data, noteval().