在这个闭包中传递的参数是什么时候?

时间:2014-04-10 16:14:27

标签: javascript closures memoization

Secrets of the JavaScript Ninja获取,代码清单5.14将 isPrime num 参数传递给 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)仅在内部闭包(#2)中可见,而在包装memoize函数中不可见?我不明白memoize()在何时调用 num参数传递给#2中的闭包。

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

谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

我不明白memoize()调用在哪一点将num参数传递给#2中的闭包。

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

答案 1 :(得分:1)

因为在那时,匿名函数已被调用。

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

然后

memoize返回一个函数,该函数基本上检查&#34;是否已使用此参数&#34;调用此函数,如果是,则返回先前的值,或者调用函数并存储其返回值如果没有价值。

这意味着您的功能仅在您实际执行isPrime(17)时被调用,此时您的功能位于return function() {...}所在的功能内,您可以在其中查看你的论点。