JavaScript Memoization

Memoization is a powerful optimization technique in JavaScript that stores the results of expensive function calls and returns the cached result when the same inputs occur again.

This technique can drastically improve performance for functions with repeated calls and deterministic outputs.



What is Memoization?

Memoization is a way to make your programs faster by remembering the results of expensive function calls.

Imagine you ask a friend to solve a tough math problem. The first time it takes a while. But if you ask the same question again, they remember the answer instead of solving it again. That’s what memoization does — it remembers results to avoid repeating work.

Here’s a very simple example:

javascript
function slowAdd(a, b) {
  console.log("Doing a slow calculation...");
  return a + b;
}



function memoizedAdd(a, b) {
const memo = {};
  const key = a + "," + b;

  if (memo[key]) {
    return memo[key]; // return saved result
  } else {
    const result = slowAdd(a, b); // do the work
    memo[key] = result;           // save it
    return result;
  }
}

console.log(memoizedAdd(3, 4)); // Does the work
console.log(memoizedAdd(3, 4)); // Uses saved result

What Happens Here:

  • 1. slowAdd(a, b): This function adds two numbers and prints a message to show it's doing a "slow" calculation. (You can imagine it takes time.)
  • 2. memo: This is a plain object (like a box) that stores past results. The keys are the inputs (like "3,4") and the values are the answers.
  • 3. memoizedAdd(3, 4): When this function is called:
    • It checks if the result for "3,4" is already saved in memo.
    • Since it's the first time, it’s not there — so it calls slowAdd(3, 4) to get the answer (which prints the message).
    • Then, it saves the result (7) inside memo with the key "3,4".
  • 4. memoizedAdd(3, 4) again: This time, the function checks the memo and finds that "3,4" is already saved. So, it skips the calculation and just gives you the saved result instantly — no printed message!

Output

Doing a slow calculation...
7
7

Example 1: Memoized Fibonacci

This example shows how we can speed up a Fibonacci number calculation by remembering (or caching) past results.

javascript
function fib(n) {
  if (n <= 1) return n;
  return fib(n - 1) + fib(n - 2);
}



function memoizedFib(n) {
const memo = {};
  if (n in memo) {
    return memo[n]; // return saved result
  } else {
    const result = fib(n);
    memo[n] = result; // save result
    return result;
  }
}

console.log(memoizedFib(10)); // 55
console.log(memoizedFib(10)); // uses cached result

What Happens Here (Step-by-Step):

  • 1. Define fib(): This is a regular recursive function to find the nth Fibonacci number. But it's slow for big numbers because it repeats a lot of work.
  • 2. Create a cache: We create an empty object called memo to store answers we've already found.
  • 3. Define memoizedFib(): This function first checks if we already have the answer for n inside memo.
  • 4. If cached: If the result is already saved, it returns that value instantly — no extra work!
  • 5. If not cached: It calculates the Fibonacci number using fib(n), saves the result, and returns it.
  • 6. Output: The first call to memoizedFib(10) calculates and saves the result. The second call just uses the saved value.

Output

55
55

Example 2: Memoized Factorial

This example shows how we can speed up the calculation of a factorial number by saving (caching) results we already know.

javascript
function factorial(n) {
  if (n === 0) return 1;
  return n * factorial(n - 1);
}



function memoizedFactorial(n) {
const memo = {};
  if (n in memo) {
    return memo[n]; // Return saved result if available
  } else {
    const result = factorial(n);
    memo[n] = result; // Save the result in cache
    return result;
  }
}

console.log(memoizedFactorial(5)); // 120
console.log(memoizedFactorial(5)); // uses cached result

What Happens Here (Step-by-Step):

  • 1. Define factorial(): This is a simple recursive function to calculate the factorial of a number n (which means multiplying all numbers from 1 to n).
  • 2. Create a cache: We make an empty object called memo to store answers we calculate.
  • 3. Define memoizedFactorial(): This function first checks if the factorial of n is already saved in memo.
  • 4. If cached: If yes, it returns the saved result immediately, skipping the calculation.
  • 5. If not cached: It calls the normal factorial() function, saves the result in memo, then returns it.
  • 6. Output: The first call to memoizedFactorial(5) calculates and caches the answer (120). The second call instantly returns the cached result.

Output

120
120

Frequently Asked Questions

What is memoization in JavaScript?

Memoization is a technique used in JavaScript to store the results of expensive function calls and reuse the cached result when the same inputs occur again. It helps improve performance by avoiding redundant calculations.


When should I use memoization?

Use memoization when a function is deterministic and called repeatedly with the same arguments. It's especially useful in recursive computations like fibonacci or factorial.


What is the difference between memoization and caching?

Memoization is a type of caching focused on function return values based on input arguments. General caching can apply to anything, like API responses or static assets.


Is memoization the same as dynamic programming?

Memoization is a technique often used in dynamic programming. Dynamic programming involves breaking down problems into smaller parts and solving each just once by storing the results.


Can I memoize functions with multiple arguments?

Yes, but you’ll need a unique key for each combination of arguments. A common strategy is to use JSON.stringify(arguments) or custom key formatting to ensure uniqueness.



What's Next?

Next, you’ll learn about currying in JavaScript. Currying is a way to break down a function that takes multiple arguments into a series of smaller functions, each taking one argument at a time. This helps make your code more flexible and reusable. It might sound a little tricky at first, but with practice, you’ll see how useful it can be for writing cleaner and easier-to-understand code.