Uncle said:
var decoratedFib = function fib(n) {
return decoratedFib(n-1) + decoratedFib(n-2);
}.decorate({...});
My question:
Does "decoratedFib" get assigned "function fib" or
the result of executing "function decorate"?
Richard Cornford's answer is correct, but it's not as clear as his
prose usually is.
If you look at Javascript's operator precedence ([1]), you might note
that the member operator (".") binds well before the assignment
operator ("="), so anything of this form:
var z = x.y()
will assign to `z` the value of calling the function assigned to the
property `y` of the object `x` in the context of `x`. The fact that
in this case `x` is a function doesn't change that.
So your `decoratedFib` variable will be assigned the result of the
call to `decorate` performed on the named anonymous (!!) function.
The only way that will work is if `decorate` has been added to the
prototype chain of the anonymous function, that is, if it's on
Function.prototype (or possibly Object.prototype).
If decorate looked like this:
Function.prototype.decorate= function() {
var cache = {}, self = this;
return function(n) {
return (n in cache) ? cache[n] : (cache[n] = self(n));
};
};
then you would have a new Fibonacci function that memoized the
results, calculating larger ones much more quickly than the
undecorated version. Of course, then `decorate` should probably be
renamed `memoize`. (Note too that this is not a general-purpose
memoization function. It only works for unary functions of numbers or
strings. It's not hard to build a more general-purpose one, but it's
outside the scope of this discussion.
-- Scott
[1] One good source is
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence