2015-09-14 42 views
2

我在讀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的是一個全局變量的緩存變量不會被重置每次調用時間。但我似乎無法找到一個好的解決方案。

+1

你爲什麼認爲它*會被重置? 'memoize'返回的函數並不會改變'cache'的值,那麼會改變它呢? – Pointy

回答

2

當執行:

var squareNumber = memoize(function(x){ return x*x; }); 

memoize()內部的cache變量被初始化,並於內函數的引用被返回並分配給squareNumber。該內部函數引用了該對象,並且每次在您執行squareNumber(x)時調用該對象,該內部函數繼續引用相同的原始變量cache

這實際上是這種設計模式的預期行爲,因此緩存可以從一次調用繼續存在。

如果你想要一個新的緩存副本,那麼你必須再次調用memoize()以重新開始一個新的緩存和新的內部函數,該函數引用了新的cache變量。

僅供參考,因爲雖然memoize()已運行並完成了這個被稱爲閉合,參考到內部功能從執行memoize()回到有這樣的局部變量不是垃圾被JS所收集的memoize()局部變量的引用口譯員,儘管memoize()早已完成執行。這被稱爲封閉。

5

因爲函數memoize只被調用一次。 memoize(function(x){ return x*x; })只是給出了返回值,這恰好是一個函數。

相關問題