我正在阅读John Resig的Javascript Ninja,并且在Memoization章节中提到了这个概念,我无法弄清楚它是如何工作的。我在谷歌找不到解释时遇到了麻烦。所以,这是本书的例子。
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;
return function(){
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 don't understand how this works
现在,我理解这个例子中闭包是如何工作的,我一般都了解原型,但我不明白这个(function expression).memoize()
部分是如何工作的?我看到memoize返回一个函数,并且该函数(我推测)被添加到isPrime
,但是如何调用(function expression)
,或者它如何作为isPrime方法的一部分?那么,当我打电话给isPrime(17)
时,先执行什么?
编辑: 好吧,我现在对所有的commants感到困惑,所以这就是我现在看到它的方式。
首先:调用(function(num){....}).memoize()
时,匿名函数表达式(function(num){...})
在memoize函数中表示为this
并分配给fn。
第二:在memoize内部返回一个匿名函数,该函数通过闭包保存fn
。返回的匿名函数已分配给isPrime
第三:当我们调用isPrime(17)
时,实际上所谓的是fn.memoized.apply(fn, attributes)
,而内部的memoized this
(上下文)代表fn,它是对匿名函数的引用(函数(NUM {...}))。这部分:this.apply(this, arguments)
执行匿名函数(function(num){...})
这是有道理的,首先需要检查数字是否被缓存,如果不是,请检查它是否为素数并将其放入缓存中。
答案 0 :(得分:1)
发生以下情况:
Function
和memoized
两种方法对memoize
原型进行了扩展(但是,建议不要扩展原生原型)(function(num)...
分配给函数原型的isPrime
memoize
之前调用memoize
this
自动绑定到调用该方法的对象(本例中为函数对象)。所以this
指的是匿名函数,后来被分配给isPrime
。最后返回一个thunk return function(){...
以推迟执行。apply
将任意数量的参数传递给memoized
(请注意,提供给memoized
的第一个参数用作记忆缓存)我认为这个实现很丑陋,因为除其他外,它模糊了这样一个事实,即原始的匿名函数不是分配给isPrime
,而是包含它的thunk。
我不确定isPrime
(或匿名函数表达式)是否是IIFE,因为只是立即调用其原型的方法,而不是函数本身。