手机版

Javascript Memoizer分析

时间:2021-09-09 来源:互联网 编辑:宝哥软件园 浏览:

以下是来自约翰汉恩的实现。这段代码引起了我的注意。它以一种巧妙的方式缓存方法调用的结果。

代码解析:

复制的代码如下://memoize : memoize//func :方法缓存的常规方法要缓存的//context3360方法执行上下文//Note:方法必须是外部可访问的。该参数是字符可序列化的函数内存(func,context){函数内存arg(arg pos){//该参数指示参数var cache={}在原始方法中的位置;//缓存的键是参数,值是执行结果返回函数(){//如果(argPos==0)则返回函数闭包{//第一个参数,如果缓存的键中不存在该参数,则执行原函数并存储执行结果if(!(参数[argPos]在缓存中)){缓存[参数[argPos]]=func.apply(上下文,参数);}返回缓存[参数[ArgPoS]];} else {//不是第一个参数。如果缓存键中不存在该参数,则递归执行memoizeArg方法。参数在原始方法中的位置是-1。(缓存中的参数[ArgPoS]){缓存[参数[ArgPoS]]=MemoiZearg(ArgPoS-1);}返回缓存[参数[argPos]]。应用(这个,参数);} } } var arity=func . arity | | func . length;//func参数的长度,长度属性在javascript中使用,其他属性返回memo arg(arity-1);//从最后一个参数开始递归}

使用:复制代码如下: varmem=memory(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的上述几次调用之后,形成了一棵树,每个节点都是一个闭包,每个闭包都有一个缓存,每个缓存的键都是树的一个分支:

(注:上图中的“结果”也是一个闭包,只是argPos为0)

然而,有许多方法,例如,林博伊说:

复制代码如下:函数内存(fn){ var cache={ };return function(){ var key=[];for(var i=0,l=arguments.lengthI l;i ) key.push(参数[I]);if(!(缓存中的键) )缓存[键]=fn.apply(this,arguments);返回缓存[键];};}

实现起来比较容易,但是把参数推入一个数组,然后把数组当作一个键,只支持字符串类型,所以在使用的时候需要注意(比如一个对象tostring之后,可能只看到“[object Object]”),功能比上面那个弱。

要改进这一点并不难,就是为参数设置一个单独的对象,通过使用一个ID将原来的缓存对象与这个单独的参数对象关联起来:

复制代码如下:函数调用(fn) {varcache={},args={ };返回函数(){ for(var i=0,key=args.lengthI键;i ) { if(equal(args[i],参数) )返回缓存[I];} args[key]=参数;cache[key]=fn.apply(this,引数);返回缓存[键];};}

还有一些其他的方法可以写成简洁的函数方法。

版权声明:Javascript Memoizer分析是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。