// memoize: 使用memoization來緩存的通用方法
// func: 要被緩存的方法
// context: 方法 " /> 在教室伦流澡到高潮HNP视频,强伦姧久久久久久久久久,国产亚洲精品久久久久久国模美

天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

Javascript Memoizer淺析

以下來自John Hann的實現,這段代碼引起了我的注意,它用巧妙的方法把方法調用的結果緩存起來了。

代碼解析:

復制代碼 代碼如下:
// memoize: 使用memoization來緩存的通用方法
// func: 要被緩存的方法
// context: 方法執行上下文
// Note: 方法必須是外部可訪問的,參數是可字符序列化的
function memoize (func, context) {
    function memoizeArg (argPos) { //參數表示原始方法中參數的位置
        var cache = {}; //這個緩存的key是參數,value是執行結果
        return function () { //返回一個函數閉包
            if (argPos == 0) { //第一個參數,如果參數在緩存的key中不存在,就執行原始函數并且存儲執行結果
                if (!(arguments[argPos] in cache)) {
                    cache[arguments[argPos]] = func.apply(context, arguments);
                }
                return cache[arguments[argPos]];
            }
            else { //不是第一個參數,如果參數在緩存的key中不存在,就遞歸執行memoizeArg方法,原始方法中參數的位置-1
                if (!(arguments[argPos] in cache)) {
                    cache[arguments[argPos]] = memoizeArg(argPos - 1);
                }
                return cache[arguments[argPos]].apply(this, arguments);
            }
        }
    }
    var arity = func.arity || func.length; //func參數的長度,Javascript中用length屬性,其它的用arity屬性
    return memoizeArg(arity - 1); //從最后一個參數開始遞歸
}

使用:
復制代碼 代碼如下:
var mem = memoize(func, this);  
alert(mem.call(this,1,1,2));  
alert(mem.call(this,2,1,2));  
alert(mem.call(this,3,1,3));  
alert(mem.call(this,2,2,4));

看似簡單,再一看好像也并不易懂,可是如果能對閉包的使用比較熟悉的話,就很好理解了。經過上面幾次mem.call的調用之后,形成的是一棵樹,每個節點都是一個閉包,每個閉包內有一個cache,每個cache的key都是樹分支:

(注:上面圖中的“結果”也是一個閉包,只不過argPos為0而已)

不過方法有諸多,比如limboy說:

復制代碼 代碼如下:
function Memoize(fn){
    var cache = {};
    return function(){
        var key = [];
        for( var i=0, l = arguments.length; i < l; i++ )
            key.push(arguments[i]);
        if( !(key in cache) )
            cache[key] = fn.apply(this, arguments);
        return cache[key];
    };
}

實現更簡易,不過把參數push到一個數組內,再把數組當key,而key是只支持字符串型的,因此這點在使用上需要注意(比如一個對象tostring之后可能只看到”[object Object]“了),它的功能比上面那個要弱一些。

改進這一點也不難,把參數另立一個對象即可,而原cache對象和這個另立的參數對象使用一個ID關聯起來:

復制代碼 代碼如下:
function Memoize(fn){
    var cache = {}, args = {};
    return function(){
        for( var i=0, key = args.length; i < key; i++ ) {
            if( equal( args[i], arguments ) )
                return cache[i];
        }
        args[key] = arguments;
        cache[key] = fn.apply(this, arguments);
        return cache[key];
    };
}

還有一些其他的辦法,都可以寫成簡潔的函數式方法。

JavaScript技術Javascript Memoizer淺析,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 一区二区三区国产亚洲网站 | 国产一区2区 | 久久高清免费视频 | 色欲人妻无码AV专区 | 美女爽到嗷嗷嗷叫 | 乌克兰少妇大胆大BBW | 囚禁固定在调教椅上扩张H 秋霞最新高清无码鲁丝片 秋霞在线看片无码免费 | 亚洲黄色免费在线观看 | 小776论坛| 91在线青春娱乐精品分类 | 亚洲国产高清在线观看视频 | 色欲人妻无码AV精品一区二区 | 亚洲精品乱码久久久久久v 亚洲精品乱码电影在线观看 | 亚洲国产成人精品不卡青青草原 | 99视频精品全部免费免费观 | 小鸟酱喷水 | 伊人影院香蕉久在线26 | 欧美肥婆性生活 | 夜色88V精品国产亚洲AV | 狠狠狠的在啪线香蕉 | 亚洲AV久久久噜噜噜久久 | 禁室培欲在线视频免费观看 | 超碰在线观看 | 中文字幕AV亚洲精品影视 | WWW污污污抽搐喷潮COM | 校花的奶好大好浪 | 亚洲AV 无码AV 中文字幕 | 亚洲spank男男实践网站 | 禁室培欲在线视频免费观看 | 5g在线视讯年龄确认海外禁止进入 | 99在线在线视频观看 | 精品含羞草免费视频观看 | 99青草青草久热精品视频 | 99视频免费看 | 亚洲色偷偷偷网站色偷一区人人藻 | 最新国产亚洲亚洲精品视频 | 国产色偷偷男人的天堂 | 一级毛片免费下载 | 色人阁综合 | 精品久久久麻豆国产精品 | 日本无码毛片久久久九色综合 |