函数可以将先前操作的结果记录在某个对象里,从而避免无谓的重复运算。这种优化方式被称为记忆(memoization)。JavaScript的对象和数组要实现这种优化是非常方便的。

比如说,我们想要一个递归函数来计算Fibonacci数列。一个Fib数字是之前两个Fib数字的和。最前面的两个数字是0和1。

var count=0;
var fib=function(n){
count++;
return n<2?n:fib(n-1)+fib(n-2);
};
for(var i=0;i<=10;i++){
console.log(fib(i))
} //
//
//
//
//
//
//
//
//
//
// count
//

这样是可以工作的,但它做了很多无谓的工作,fib函数被调用了453次。如果我们让该函数具备记忆功能,就可以显著地减少运算量。

我们在一个名为memo的数组里保存我们的存储结果,存储结果可以隐藏在闭包中。当函数被调用时,这个函数首先检查结果是否已经存在,如果已经存在,就立刻返回这个结果。

var count=0;
var fibonacci=function(){
var memo=[0,1];
var fib=function(n){
count++;
var result=memo[n];
if(typeof result!=='number'){
result=fib(n-1)+fib(n-2);
memo[n]=result;
}
return result;
};
return fib;
}(); for(var i=0;i<=10;i++){
console.log(fibonacci(i))
}
//结果同上 count
//

这个函数返回同样的结果,但它只被调用了29次。

我们可以把这种技术推而广之,编写一个函数来帮助我们构造带记忆功能的函数。memoizer函数取得一个初始的memo数组和formula函数。它返回一个管理memo存储和在需要时调用formula函数的recur函数。我们把这个recur函数和它的参数传递给formula函数:

var memoizer=function(memo,formula){
var recur=function(n){
var result=memo[n];
if(typeof result!=='number'){
result=formula(recur,n);
memo[n]=result;
}
return result;
};
return recur;
};

现在我们可以使用memoizer函数来定义fibonacci函数,提供其初始的memo数组和formula函数:

var fibonacci=memoizer([0,1],function(recur,n){
return recur(n-1)+recur(n-2);
});

通过设计这种产生另一个函数的函数,极大的减少了我们的工作量。例如,要产生一个可记忆的阶乘函数,我们只需提供基本的阶乘公式即可:

var factorial=memoizer([1,1],function(recur,n){
return n*recur(n-1);
});

最新文章

  1. 【先定一个小目标】在Windows下的安装Elasticsearch
  2. VS中使用svn注意事项
  3. 从request获取远程IP地址
  4. GridView控件RowDataBound事件的一个实例
  5. 关于socket——SO_SNDBUF and SO_RECVBUF
  6. javascript检验工具的比较
  7. 图像处理之泛洪填充算法(Flood Fill Algorithm)
  8. Maven项目的发布,发布到Nexus
  9. 【Android车载系统 News | Tech 2】News 谷歌开发新车载系统!安卓Auto不是终点 2014-12-20
  10. Linux 命令 - crontab: 任务调度
  11. 283. Move Zeroes(C++)
  12. jdk1.5 jdk1.6 jdk1.7 jdk1.8 下载地址
  13. android 03 TableLayout
  14. requirejs2读书笔记
  15. C#整理8——结构体
  16. opencv 中cvZero()的使用
  17. docker 数据盘映射方案
  18. Java编程入门(词汇表)
  19. 2017 年终总结 &amp; 2018 年度计划
  20. 剑指offer-反转单词顺序列

热门文章

  1. Data - 数据思维
  2. D3.js(v3)+react框架 基础部分之数据绑定及其工作过程与绑定顺序
  3. iOS开发-实现相机app的方法[转载自官方]
  4. 将python打包为.exe文件
  5. Hadoop 2.4.1+HBase 0.98.6.1 分布式安装
  6. MySQL笔记(1)---MySQL体系结构和存储引擎
  7. MySQL数据导入到Mongo
  8. js中编写velocity逻辑
  9. Selenium自动化测试Python六:持续集成
  10. poi导出联动下拉选择的excel