为什么每次调用函数时都不会重置变量

时间:2015-09-14 23:58:47

标签: javascript functional-programming

我正在阅读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是一个全局变量,因此每次调用时都不会重置缓存变量。但我似乎无法找到一个好的解决方案。

2 个答案:

答案 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()早已完成执行。这被称为闭包。

相关问题