Javascript的memoizer分析
以下来自John Hann的实施,它吸引我的注意和缓存的方法在一个聪明的方式调用的结果。代码解析:
复制代码代码如下所示:
: / / memoize一般使用memoization的缓存方法
要成为函数:缓存方法
上下文:方法执行上下文
注意:方法必须是外部可访问的,参数是序列化的字符。
功能(功能、语境memoize){
功能memoizearg(argpos){ / /参数的原始方法中参数的位置
这是一个关键参数的缓存,值是结果的实现。
返回(函数)返回函数闭包
如果(argpos = = 0){ / /第一个参数,如果参数不在关键的缓存存在,原有的功能和记忆的执行结果的实现
如果(!(论点{ argpos }在缓存)){
{ } } { argpos缓存参数= func.apply(语境参数);
}
返回缓存参数argpos } } { {;
}
{ / /不一样的第一个参数,如果参数不在关键的高速缓存的存在,一个递归memoizearg方法执行的1参数法的原始位置
如果(!(论点{ argpos }在缓存)){
{ } } { argpos缓存参数= memoizearg(argpos - 1);
}
返回缓存参数argpos } } { {申请(这论点);
}
}
}
无功度= func.arity func.length | |;的 / /函数参数的长度,在Javascript中使用长度属性,与该属性的其他
返回memoizearg(元1); / /从最后一个参数递归
}
使用uff1a
复制代码代码如下所示:
VaR MEM = memoize(函数,这个);
警报(mem.call(,1));
警报(mem.call(,2));
警报(mem.call(这3,1,3));
警报(mem.call(这,2,2,4));
它看起来很简单,看起来并不容易理解,但如果你熟悉的封闭使用,这将是很好的理解。经过几mem.call调用,形成一棵树。每个节点都是一个闭包。每个闭包都有一个缓存,每个缓存的密钥都是树的分支。
(注:上图中的结果也是一个闭包,但只有argpos 0)。
但有许多方法,如limboy。
复制代码代码如下所示:
功能memoize(FN){
var;
返回函数(){
var;
对于(var i = 0,L = arguments.length;i < L;i++)
Key.push(参数{我});
如果(!(缓存中的键)
缓存{key} = fn.apply(这个参数);
返回缓存{ };
};
}
要实现更简单,但参数推到一个数组,数组的键时,键是唯一支持字符串类型,所以需要使用注意(例如toString对象可能只看到{物}),其功能较弱。
这种改进并不困难,可以建立一个对象的参数,以及原始缓存对象和使用id关系的其他对象的参数:
复制代码代码如下所示:
功能memoize(FN){
var args缓存= = { } { };
返回函数(){
对于(var i = 0,关键= args.length;我<关键;i++){
如果(平等(args {我},参数))
返回缓存{ };
}
{ } =争论的关键参数;
缓存{key} = fn.apply(这个参数);
返回缓存{ };
};
}
还有其他方法可以写成简单的函数方法。