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?

Van
  • 618
  • 3
  • 14
  • 2
    Possible duplicate of [What is the meaning of "...args" (three dots) in a function definition?](https://stackoverflow.com/questions/42184674/what-is-the-meaning-of-args-three-dots-in-a-function-definition) – AndrewL64 Jan 14 '19 at 09:30
  • @AndrewL edited the question to add some clarification on the part that I don't really understand. Thanks! – Van Jan 14 '19 at 09: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". – slebetman Jan 14 '19 at 10:04

1 Answers1

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
Harshit Juneja
  • 325
  • 2
  • 11