4

I was looking at an article about memoize function in JavaScript and stumbled upon the example below

// same memoize function from before
const memoize = (fn) => {
  let cache = {};
  return (...args) => {
    let n = args[0];
    if (n in cache) {
      console.log('Fetching from cache', n);
      return cache[n];
    }
    else {
      console.log('Calculating result', n);
      let result = fn(n);
      cache[n] = result;
      return result;
    }
  }
}
const factorial = memoize(
  (x) => {
    if (x === 0) {
      return 1;
    }
    else {
      return x * factorial(x - 1);
    }
  }
);
console.log(factorial(5)); // calculated
console.log(factorial(6)); // calculated for 6 and cached for 5

In the memoize function above, how is the args variable defined/come to be? Could anyone help me to understand it?

const memoize = (fn) => {
  let cache = {};
  return (...args) => {
...

From the call, it seems that the args is just a variable for the arguments/params from the passed function fn but I am unable to wrap my head on why and how the code block above is working.

Also, is there a name for this code/design pattern?

Edit I have read about arguments and rest parameters. However the part that I don't understand is how come the ...args inside memoize function become the parameters from the passed function fn? Shouldn't arguments object or rest parameter ...args only represents the parameters/arguments from the current function memoize, i.e. the fn argument? And in that case args[0] is the function fn?

3
  • 2
    Possible duplicate of What is the meaning of "...args" (three dots) in a function definition? Commented Jan 14, 2019 at 9:30
  • @AndrewL edited the question to add some clarification on the part that I don't really understand. Thanks! Commented Jan 14, 2019 at 9:41
  • 1
    It's an argument. It's defined just like (fn) or (x). You're looking at it: (...args). That's the definition right there. Now, the novel thing is the ... syntax.. and that's called "rest parameters". Commented Jan 14, 2019 at 10:04

1 Answer 1

1

Don't confuse it as arguments of fn getting magically passed in the returned function. You are correct with your understanding of functions and scope.

If I refactor the code, this is how it looks like.

const memoize = () => {
  //just renamed the returned function to somefn
  return somefn(); 
}

const somefn = (...args) => {
// somefn takes x as argument when we called factorial(x)
  let cache = {};
  let n = args[0];
  if (n in cache) {
    console.log('Fetching from cache', n);
    return cache[n];
  }
  else {
    console.log('Calculating result', n);
    let result = foo(n);
    cache[n] = result;
    return result;
  }
}

//your business logic is in foo now
const foo = (x) => {
  if (x === 0) {
    return 1;
  }
  else {
    return x * factorial(x - 1);
  }
}

const factorial = memoize(foo);

console.log(factorial(5)); // calculated
Sign up to request clarification or add additional context in comments.

1 Comment

If you need any further explanation, Please comment. Otherwise, an upvote is much appreciated :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.