Lesson 17 of 80
Caching a function's results by its arguments, so calling it again with the same input skips the work entirely — a closure holding a cache instead of a timer.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 2
Why is memoization only safe for pure functions?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Memoization wraps a function with a cache: before running the real work, check if this exact input was seen before. If yes, return the stored answer. If no, compute it, store it, then return it.
function memoize(fn) {
const cache = new Map(); // lives in the closure, one per wrapped function
return function (arg) {
if (cache.has(arg)) return cache.get(arg);
const result = fn(arg);
cache.set(arg, result);
return result;
};
}
const slowSquare = (n) => { /* expensive work */ return n * n; };
const fastSquare = memoize(slowSquare);
fastSquare(5); // computes, caches
fastSquare(5); // returns cached instantly, doesn't call slowSquare again
This is the exact same shape as debounce: a function returns another function that closes over some private state (there, a timer; here, a cache) that survives between calls.
fastSquare(5) — not in the cache yet. Compute it the slow way, then store the result.
WeakMap when the key is an object, so entries can be garbage-collected.Map keyed on one argument doesn't work for fn(a, b) — you typically serialize the arguments (JSON.stringify([a, b])) or nest maps.useMemo/useCallback are this exact idea, applied to a component's renders instead of a plain function's calls — "skip recomputation if the inputs haven't changed."Memoized Fibonacci ("naive recursive fib is exponential, memoized fib is linear") is a classic exercise that checks whether you can connect closures, recursion, and time-complexity reasoning in one answer.