Cory Gross
Cory Gross

Reputation: 37206

Why is this second closure needed in John Resig's JavaScript?

I am reading Secrets of the JavaScript Ninja by John Resig and Bear Bibeault, currently up to Chapter 5 on closures. I think have the general gist of closures and how JavaScript operates with function scoping rather than the block scoping of C++/Java of which I am familiar. One thing I am having trouble understanding fully though is sometimes in the code there seem to be more function declarations than I can figure out purposes for. For instance, in Section 5.5.1 He covers self-memoizing functions, which is basically a function that remembers computed values and stores them in a cache for subsequent calls with the same input. He gives the following code:

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

Function.prototype.memoize = function () {                        // #2
    var fn = this;
    return function() {                                           // #2.1
        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();

I understand most of this code. However what I am having trouble understanding is why at the second memoization function couldn't simply be:

Function.prototype.memoize = function () {                      
    return this.memoized.apply(fn, arguments);
};

Can anyone give me a good explanation of what is happening in his code above and how it is different than what I have written here?

Upvotes: 4

Views: 368

Answers (1)

kapa
kapa

Reputation: 78731

There is quite a big difference:

return function() {
    return fn.memoized.apply(fn, arguments);
};

returns a function that you can call later. memoized is only called when the function is called.

return this.memoized.apply(fn, arguments);

calls the function memoized and returns its return value.

Upvotes: 3

Related Questions