内容要点:   可以将上次的计算结果缓存起来。在函数式编程当中,这中缓存技巧叫做 "记忆"。

需要注意的是,记忆只是一种编程技巧,本质上是牺牲算法的空间复杂度以换取更优的时间复杂度,在客户端JS中代码代码执行的时间复杂度往往成为瓶颈,因此在大多数场景下,这种牺牲空间换取时间的做法以提升程序执行效率的做法是非常可取的。

一.memorize()函数

下面的代码展示了一个高阶函数,memorize()接收一个函数作为实参,并返回带有记忆能力的函数。

//返回f()的带有记忆功能的版本

//只有当f()的实参的字符串表示都不相同它才会工作

function memorize(f){

var cache = {}; //将值保存在闭包内

return function(){

//将实参转换为字符串形式,并将其用做缓存的键

var key = arguments.length + Array.join.call(arguments,",");

if(key in cache) return cache[key];

else return cache[key] = f.apply(this,arguments);

};

}

代码分析:

memorize()函数创建一个新的对象,这个对象被当做缓存(的宿主)并赋值给一个局部变量,因此对于返回的函数来说它是私有的(在闭包中)。所返回的函数将它的实参数组转换成字符串,并将字符串用做缓存对象的属性名。如果在缓存中存在这个值,则直接返回它。

否则,就调用既定的函数对实参进行计算,将计算结果缓存起来并返回,下面的代码展示了如何使用memorize():

//返回两个整数的最大公约数

//使用欧几里德算法:

function gcd(a,b){   //这里省略对a和b的类型检查

var t;                  //临时变量用来存储交换数值

if(a<b) t=b,b=a,a=t;     //确保a>=b

while(b!=0) t=b,b=a%b,a=t; //这是求最大公约数的欧几里德算法

return a;

}

var gcdmemo = memorize(gcd);

gcdmemo(85,187) //=>17

//注意,当我们写一个递归函数时,往往需要实现记忆功能

//我们更希望调用实现了记忆功能的递归函数,而不是原递归函数

var factorial = memorize( function(n){ return (n<=1) ? 1 : n*factorial(n-1); });

factorial(5); //=>120.对于4-1的值也有缓存

《JS权威指南学习总结--8.8.4 记忆函数》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 使用java连接MySql,中文乱码解决的方法

    排查MySql中文乱码的问题 1.在cmd中启动MySql. 打开命令提示符cmd,输入"mysql -uusername -ppassword",回车,就可以连接到数据库. 如输 ...

  2. jQuery基础教程第四版练习答案

    第二章 1. $('#selected-plays>li>ul>li').nextAll().addBack().addClass('special'); 2. $('table') ...

  3. 关于java集合排序

    对于排序,java开发者并不陌生. 为避免以后遗忘,现在再次总结一下! 常见8大排序算法, 平时自己熟悉的只有几种种!冒泡,二分/折半.插入.快排等!现在一一讲解一下,这里只讲思想,暂时不做实现! 一 ...

  4. Winform ComBox模糊查询

    一.添加数据源并绑定 List<string> list = new List<string>(); list.Add("张三"); list.Add(&q ...

  5. [HMLY]3.如何使用Xcode Targets管理开发和生产版本?

    本文原地址:http://www.appcoda.com/using-xcode-targets/ 在开始此教程之前,我们假设你已经完成了应用程序的开发和测试,现在准备提交生产发布.问题是,某些web ...

  6. inux按照CPU、内存、磁盘IO、网络性能监测

    http://my.oschina.net/chape/blog/159640 系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长 ...

  7. vertical-align属性详解

    vertical-align属性详解:http://www.cnblogs.com/wcp-spring/archive/2013/03/04/2942456.html 关于vertical-alig ...

  8. SQL Server2012中的SequenceNumber

    http://www.cnblogs.com/CareySon/archive/2012/03/12/2391581.html https://q.cnblogs.com/q/53552/ https ...

  9. Filewatcher

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...

  10. MySql 安装过程(摘自网络)

    下面的是MySQL安装的图解,用的可执行文件安装的,详细说明了一下! 打开下载的mysql安装文件mysql-5.0.27-win32.zip,双击解压缩, 运行“setup.exe”,出现如下界面 ...