我正在阅读Professor Frisby's Mostly adequate guide to functional programming,我看到了下面显示的代码示例。我不明白为什么每次调用squareNumber时缓存都不会重置为{}。
var memoize = function(f){
var cache = {}; // why is this not reset each time squareNumber is called?
return function() {
var arg_str = JSON.stringify(arguments);
cache[arg_str] = cache[arg_str]|| f.apply(f, arguments);
return cache[arg_str];
};
}
var squareNumber = memoize(function(x){ return x*x; });
squareNumber(4);
//=> 16
squareNumber(4); // returns cache for input 4
//=> 16
squareNumber(5);
//=> 25
squareNumber(5); // returns cache for input 5
//=> 25
我的一个理论是,由于memoize是一个全局变量,因此每次调用时都不会重置缓存变量。但我似乎无法找到一个好的解决方案。
答案 0 :(得分:5)
因为函数memoize
只被调用一次。 memoize(function(x){ return x*x; })
只是给出了返回值,恰好是一个函数。
答案 1 :(得分:2)
执行时:
var squareNumber = memoize(function(x){ return x*x; });
初始化cache
内的memoize()
变量,并返回对内部函数的引用并将其分配给squareNumber
。该内部函数具有对该cache
对象的引用,并且每次在执行squareNumber(x)
时调用该内部函数时,该内部函数将继续引用该同一原始cache
变量。
这实际上是此设计模式的预期行为,因此缓存可以从一次调用持续到下一次调用。
如果你想要一个新的缓存副本,那么你必须再次调用memoize()
来重新开始使用一个新的缓存和新的内部函数,它具有对新cache
变量的引用。
仅供参考,这称为闭包,因为尽管memoize()
已经运行并完成,但对执行memoize()
返回的内部函数的引用引用了memoize()
的局部变量所以这些局部变量不是由JS解释器收集的,即使memoize()
早已完成执行。这被称为闭包。