Problem
Implement memoize(fn) for any number of arguments, including primitives, objects, arrays, and functions. Repeated calls reuse the result only when the ordered tuple contains the same primitive values and the same object or function references.
Requirements
- Different objects with identical properties are different keys. The same object reference is a cache hit.
- Different function references are different keys, even when their source code looks identical.
- Support mixed arguments, circular objects, and zero-argument calls.
- Do not serialize objects or functions. Inputs must remain unmodified.
- Cache every returned value, including
undefined,null,false,0, and empty strings. - Each wrapper has its own cache. Exceptions are not cached.
- Forward the caller's
thiswhen computing a result. Assume results depend only on the arguments; caching across different receivers is outside this problem. - Compare primitive keys using
Mapequality:NaNmatchesNaN, and0matches-0. - The function is synchronous and deterministic. Cache eviction and async rejection handling are follow-ups.
- Assume referenced inputs do not mutate after caching. Mutating an object does not invalidate its cached entry.
Example
let calls = 0;
const run = memoize((obj, transform) => { calls++; return transform(obj.value); });
const item = { value: 3 };
const double = n => n * 2;
run(item, double); // 6, computed
run(item, double); // 6, cached
run({ value: 3 }, double); // 6, computed: new object
run(item, n => n * 2); // 6, computed: new function
console.log(calls); // 3
Starter code
function memoize(fn) {
// Your code here
}