Q29: Implement a memoize() utility for caching function results.
Answer
Memoization caches the result of a function call so repeated calls with the same inputs can reuse the previous result.
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.apply(this, args);
cache.set(key, result);
return result;
};
}
const slowSquare = memoize(n => {
console.log("Calculating...");
return n * n;
});
console.log(slowSquare(5)); // Calculates... 25
console.log(slowSquare(5)); // 25, retrieved from cache
Explanation
The wrapper computes a cache key from the arguments. If the key exists, it returns the stored result; otherwise, it calls the original function and caches the result.
Interview edge cases
JSON.stringify()can produce collisions for certain inputs and cannot serialize all JavaScript values.- Object identity is not preserved by JSON serialization.
- The receiver,
this, may affect the function's result but is not included in the key. - Unbounded caches can grow indefinitely.
A production implementation should choose a cache-key strategy appropriate to the function's inputs. For a function that accepts only primitive arguments, a nested Map structure can provide safer key semantics.
Key Takeaways
- Memoization reuses results for repeated inputs.
- Cache keys and cache invalidation must be designed carefully.