Problem
Implement memoize(fn) for a function that receives exactly one primitive argument. The returned wrapper must compute the result once for each distinct argument and reuse it on subsequent calls. Primitive arguments include numbers, strings, booleans, null, undefined, bigint, and symbols. Objects and functions are reserved for Memoize III.
Requirements
- Calls always supply exactly one argument.
- 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.
Example
let calls = 0;
const square = memoize(n => { calls++; return n * n; });
square(4); // 16, computed
square(4); // 16, cached
square(5); // 25, computed
console.log(calls); // 2
Starter code
function memoize(fn) {
// Your code here
}