How to create a memoization function in JavaScript

Memoization caches function results based on input arguments, dramatically improving performance for expensive computations. As the creator of CoreUI with 25 years of JavaScript optimization experience, I’ve used memoization to reduce calculation times from seconds to milliseconds in production applications.

The most effective approach creates a higher-order function that wraps the target function with a caching layer.

Direct Answer

Create a memoization wrapper that caches results by argument signature.

const memoize = (fn) => {
  const cache = new Map()

  return (...args) => {
    const key = JSON.stringify(args)

    if (cache.has(key)) {
      return cache.get(key)
    }

    const result = fn(...args)
    cache.set(key, result)
    return result
  }
}

Usage Example

const fibonacci = memoize((n) => {
  if (n <= 1) return n
  return fibonacci(n - 1) + fibonacci(n - 2)
})

console.log(fibonacci(40)) // Fast: 102334155
console.log(fibonacci(40)) // Instant: cached result

Advanced Memoization

With custom cache key and size limit:

const memoize = (fn, options = {}) => {
  const {
    maxSize = 100,
    keyGenerator = (...args) => JSON.stringify(args)
  } = options

  const cache = new Map()

  return (...args) => {
    const key = keyGenerator(...args)

    if (cache.has(key)) {
      return cache.get(key)
    }

    const result = fn(...args)

    if (cache.size >= maxSize) {
      const firstKey = cache.keys().next().value
      cache.delete(firstKey)
    }

    cache.set(key, result)
    return result
  }
}

const expensiveCalculation = memoize(
  (a, b) => {
    console.log('Computing...')
    return a * b + Math.random()
  },
  {
    maxSize: 50,
    keyGenerator: (a, b) => `${a}-${b}`
  }
)

Memoize Object Methods

const memoizeMethod = (target, propertyKey, descriptor) => {
  const originalMethod = descriptor.value
  const cache = new Map()

  descriptor.value = function(...args) {
    const key = JSON.stringify(args)

    if (cache.has(key)) {
      return cache.get(key)
    }

    const result = originalMethod.apply(this, args)
    cache.set(key, result)
    return result
  }

  return descriptor
}

class Calculator {
  @memoizeMethod
  factorial(n) {
    if (n <= 1) return 1
    return n * this.factorial(n - 1)
  }
}

WeakMap for Object Arguments

For objects as arguments, use WeakMap to prevent memory leaks:

const memoize = (fn) => {
  const cache = new WeakMap()

  return (obj) => {
    if (cache.has(obj)) {
      return cache.get(obj)
    }

    const result = fn(obj)
    cache.set(obj, result)
    return result
  }
}

const processUser = memoize((user) => {
  return {
    fullName: `${user.firstName} ${user.lastName}`,
    age: new Date().getFullYear() - user.birthYear
  }
})

Clear Cache

Add cache management:

const memoize = (fn) => {
  const cache = new Map()

  const memoized = (...args) => {
    const key = JSON.stringify(args)

    if (cache.has(key)) {
      return cache.get(key)
    }

    const result = fn(...args)
    cache.set(key, result)
    return result
  }

  memoized.clear = () => cache.clear()
  memoized.delete = (...args) => cache.delete(JSON.stringify(args))
  memoized.size = () => cache.size

  return memoized
}

const calculate = memoize((n) => n * 2)
console.log(calculate.size()) // 0
calculate(5)
console.log(calculate.size()) // 1
calculate.clear()

Best Practice Note

This is the same memoization pattern we use in CoreUI components for expensive rendering calculations. Memoization is most effective for pure functions with repeated calls and limited argument variations. For React components, use React.memo() instead.

For related performance optimizations, check out how to debounce a function in JavaScript and how to optimize loop performance in JavaScript.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.

Answers by CoreUI Core Team