2014-03-13 80 views
0

所以我非常喜歡面向對象的JavaScript。我想要的是創建一個簡單的全局對象(如jQuery,_,d3等),您可以使用一個參數作爲函數調用。然後它檢查它是否已經知道該參數,如果是,則返回緩存的信息。否則,它會在返回之前獲取新信息並將其緩存。因此,相當於:創建一個簡單的JS對象來修改自己

var cache = {}; 

function foo(arg) { 
    if (!cache[arg]) cache[arg] = doSomething(arg); 
    return cache[arg]; 
} 

function doSomething(arg) { 
    return arg+"!!!"; 
} 


foo("hi"); //returns "hi!!!" after calling doSomething 
foo("hi"); //returns "hi!!!" from cache without calling doSomething 

我無法弄清楚如何捲起緩存爲富本身,以便它檢查/調用,而不是隻使用一個單獨的全局變量的時候更新自己的哈希值。我知道,如果我做了這樣的事情會工作:

function cacher() { 
    this.cache = {}; 
} 

cacher.prototype = { 
    update: function(arg) { 
     if (!this.cache[arg]) this.cache[arg] = doSomething(this.cache[arg]); 
     return this.cache[arg]; 
    } 
} 

但在這種情況下,我不得不打電話foo.update(),而不是僅僅foo()。後者是我想要的。

任何幫助非常感謝。

回答

0

功能是對象,並且往往得心應手的人在那:

function foo(arg) { 
    if (!foo["cache"+arg]) foo["cache"+arg] = doSomething(arg); 
    return foo["cache"+arg]; 
} 

當然,這僅適用於唯一的字符串和數字參數;它會將「1」與1混淆。 它也不會緩存返回false,0,「」等。 如果對您很重要,請使用WeakMaps查看需要強類型查找功能的應用程序。

+0

笑;我只是downvote driveby的受害者,你說「爲什麼」他們說「再見」... – dandavis

+0

發生在我們最好的和最壞的...... :( –

+0

@ dandavis該車明顯高速行駛。 – sabof

-1

我前段時間寫過一個函數,它將一個「常規」函數轉換爲一個按您所描述的函數執行的函數。像這樣使用它:var cachedFunction = memoize(regularFunction)。緩存保存在閉包中。應該使用任意數量的參數。

function memoize(oriFunc) { 
    var cache = []; 
    var notFound = {}; 

    function arrayEqual(arr1, arr2) { 
    if (arr1.length !== arr2.length) { 
     return false; 
    } 
    var ri = arr1.length; 
    while (ri--) { 
     if (arr1[ri] !== arr2[ri]) { 
     return false; 
     } 
    } 
    return true; 
    } 

    function cacheGet(newArgs) { 
    var ri = cache.length; 
    while (ri--) { 
     var item = cache[ri]; 
     if (arrayEqual(item.args, newArgs)) { 
     return item.result; 
     } 
    } 

    // I'm returning a special object, since false, -1, or undefined could be 
    // results of the call 

    return notFound; 
    } 

    function cachePut(args, result) { 
    cache.push({args: args, result: result}); 
    return result; 
    } 

    return function() { 
    var cacheResult = cacheGet(arguments); 
    if (cacheResult !== notFound) { 
     return cacheResult; 
    } 
    var freshResult = oriFunc.apply(this, arguments); 
    return cachePut(arguments, freshResult); 
    }; 
} 
0

對於封裝緩存類的外觀如何?

var foo = (function() { 

    function cacher() { 
     this.cache = {}; 
    } 

    cacher.prototype.update = function(arg) { 

     if (!this.cache[arg]) this.cache[arg] = this.doSomething(this.cache[arg]); 

     return this.cache[arg]; 
    } 

    cacher.prototype.doSomething = function(arg) { 
     //Do something with arg and return 
    } 

    var func = new cacher(); 

    return function(arg) { 
     return func.update(arg); 
    } 

}()); 

var val = foo("checking"); 

你可以讓你的緩存類複雜如你一個簡單的界面需要它,在這種情況下foo將是私人範圍,函數的返回值,這需要一個參數,並使用緩存類生成價值。

0

我不知道這是否是你正在尋找真正的內容,但靜態變量似乎解決您的問題,這樣的:

 
    function foo(arg) 
    { 
     if (typeof foo.mycache == 'undefined') 
     foo.mycache = {}; 
     if (typeof foo.mycache[arg] == 'undefined') 
     foo.mycache[arg] = doSomething(arg); 
     return (foo.mycache[arg]); 
    } 
    function doSomething(arg) 
    { 
     return arg+"!!!"; 
    }
相關問題