【问题标题】:At which point is the argument passed in this closure?在这个闭包中传递的参数是什么时候?
【发布时间】:2014-04-10 16:14:26
【问题描述】:

取自Secrets of the JavaScript Ninja,代码 5.14 将 isPrimenum 参数传递给 memoized 函数,我假设 num 参数在 #1 中可见,而在 #2 中不可见,但实际上是相反的!

Function.prototype.memoized = function(key){
  this._values = this._values || {};
  return this._values[key] !== undefined ?
    this._values[key] :
    this._values[key] = this.apply(this, arguments);
};

Function.prototype.memoize = function() {
  var fn = this;                                  //#1
  console.log(Array.prototype.slice.call(arguments)); // Prints []

  return function(){                              //#2
    console.log(Array.prototype.slice.call(arguments)); //Prints [17]
    return fn.memoized.apply(fn, arguments);
  };
};

var isPrime = (function(num) {
  var prime = num != 1;
  for (var i = 2; i < num; i++) {
    if (num % i == 0) {
      prime = false;
      break;
    }
  }
  return prime;
}).memoize();

assert(isPrime(17), "17 is prime");                //#3

num 参数(在这种情况下为 17)怎么可能只在 inner 闭包(#2)中可见,而在包装 memoize 函数中不可见?我不明白 memoize() 调用何时将 num 参数传递给 #2 中的闭包。

PS。重申并补充上述问题:为什么我在 #1 中看不到 num 参数?

谢谢。

【问题讨论】:

    标签: javascript closures memoization


    【解决方案1】:

    因为#2 是分配给isPrime 的函数。然后你将17 传递给isPrime。另一方面,您调用 .memoize (#1) 时没有传递任何参数:

    (function() { ... }).memoize()
    //                          ^^ no arguments
    

    我不明白 memoize() 调用何时将 num 参数传递给 #2 中的闭包。

    它没有。 memoize 返回一个新函数,它就是传递参数的那个函数。

    【讨论】:

    • 所以 memoize 调用,真的是调用内部匿名闭包,对吧?这有点令人困惑,因为 #1 的上下文实际上是 isPrime 函数,而 #2 是 window。这就是为什么它对我没有意义。你能解释一下吗?感谢您的回复!
    • this 的工作原理在MDN documentation 中有很好的解释。基本上,如果你调用一个函数“normall”,比如foo(),那么this指的是window,如果你调用它为bar.foo(),那么this指的是bar。因此,在您的情况下,当您致电func.memoize() 时,this 指的是func“所以 memoize 调用,实际上是在调用内部匿名闭包,对吗?” 这不是 调用 内部函数。它正在创建并返回它。
    【解决方案2】:

    因为此时匿名函数还没有被调用。

    您正在做的是调用memoize,将您的匿名函数作为this 值并且没有参数(因此是空的arguments 数组)

    memoize 然后返回一个函数,该函数基本上检查“是否已经使用此参数调用了此函数”,如果是则返回先前的值,否则调用该函数并存储其返回值。

    这意味着您的函数仅在您实际执行 isPrime(17) 时才被调用,此时您位于函数内部,它显示 return function() {...},您可以在此处看到您的论点。

    【讨论】:

    • 先生,我还有一个问题要问您...为什么匿名闭包中的上下文(this)是窗口对象?上下文不应该是它的包装功能吗?感谢您的友好回复,(很难知道该给谁接受答案,两个答案都很棒)
    • 您正在调用isPrime(17),此调用中没有给出上下文,因此上下文“默认”为窗口对象。
    猜你喜欢
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    相关资源
    最近更新 更多