【问题标题】:Passed function parameters inside another function在另一个函数中传递函数参数
【发布时间】:2019-06-08 06:36:38
【问题描述】:

我在看一篇关于 JavaScript 中 memoize 函数的文章,偶然发现了下面的例子

// 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

在上面的 memoize 函数中,args 变量是如何定义/产生的?谁能帮我理解一下?

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

从调用来看,args 似乎只是传递函数fn 的参数/参数的变量,但我无法理解上面的代码块为什么以及如何工作。

另外,这个代码/设计模式有名字吗?

编辑我已经阅读了argumentsrest parameters。但是我不明白的部分是 memoize 函数内部的...args 是如何成为传递函数fn 的参数的? arguments 对象或剩余参数...args 不应该只代表来自当前函数memoize 的参数/参数,即fn 参数吗?在那种情况下args[0] 是函数fn

【问题讨论】:

  • @AndrewL 编辑了这个问题,对我不太了解的部分进行了澄清。谢谢!
  • 这是一个论点。它的定义就像(fn)(x)。您正在查看它:(...args)。这就是那里的定义。现在,新奇的东西是... 语法......这就是所谓的“休息参数”。

标签: javascript ecmascript-6


【解决方案1】:

不要将它与 fn 的参数混淆,因为它神奇地传递到返回的函数中。 您对功能和范围的理解是正确的。

如果我重构代码,这就是它的样子。

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

【讨论】:

  • 如果您需要任何进一步的解释,请发表评论。否则,非常感谢您的支持:)