Memoization

Difficulty: Intermediate

Question

What is memoization in JavaScript? How do you implement it and when should you use it?

Answer

Memoization is an optimization that caches the results of expensive function calls based on their inputs. If called again with the same arguments, the cached result is returned instead of recomputing.

Requirements: - The function must be pure (same input → same output, no side effects) - Arguments must be serializable to use as cache keys

Use cases: recursive algorithms (Fibonacci), expensive computations, React.useMemo for component rendering.

Code examples

Generic Memoize and Fibonacci

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 fib = memoize(function(n) {
  if (n <= 1) return n;
  return fib(n - 1) + fib(n - 2);
});

console.log(fib(10));
console.log(fib(10));
console.log(fib(11));

JSON.stringify converts args to a cache key. The memoized Fibonacci avoids exponential re-computation.

WeakMap-based Memoization for Objects

function memoizeWeak(fn) {
  const cache = new WeakMap();
  return function(obj) {
    if (cache.has(obj)) return cache.get(obj);
    const result = fn(obj);
    cache.set(obj, result);
    return result;
  };
}

const processUser = memoizeWeak(user => {
  console.log('Processing user...');
  return {
    displayName: `${user.firstName} ${user.lastName}`,
    initials: `${user.firstName[0]}${user.lastName[0]}`
  };
});

const alice = { firstName: 'Alice', lastName: 'Smith' };
console.log(processUser(alice).displayName);
console.log(processUser(alice).displayName);

WeakMap memoization lets the GC collect the cache when the object is no longer referenced.

Key points

Concepts covered

Memoization, Caching, Performance, Pure Functions