Question

Taken from Secrets of the JavaScript Ninja, Listing 5.14 passes the num argument of isPrime to a memoized function, I assumed the num argument would be visible in #1, and not in #2, But it's actually The other way around!

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

How is it possible that the num argument (17 in this case) is visible only in the inner closure (#2) and not in the wrapping memoize function? I don't understand at which point the memoize() call passes the num argument to the closure in #2.

PS. To reiterate, and complement the Question above: Why can't I see the num argument in #1?

Thank you.

Was it helpful?

Solution

Because #2 is the function that is assigned to isPrime. And you pass 17 to isPrime. On the other hand, you call .memoize (#1) without passing any arguments to it:

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

I don't understand at which point the memoize() call passes the num argument to the closure in #2.

It doesn't. memoize returns a new function and it's that function to which the argument is passed.

OTHER TIPS

Because at that point, the anonymous function has't been called.

What you are doing is calling memoize, with your anonymous function as the this value and no arguments (hence the empty arguments array)

memoize then returns a function, which basically checks "has this function already been called with this argument", and either return the previous value if so, or calls the function and stores its return value if not.

What this means is that your function is only called when you actually do isPrime(17), and at that point your are inside the function where it says return function() {...} and that's where you can see your argument.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top