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

需要注意的是,记忆只是一种编程技巧,本质上是牺牲算法的空间复杂度以换取更优的时间复杂度,在客户端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. 办理卡尔加里大学(本科)学历认证『微信171922772』calgary学位证成绩单使馆认证University of calgary

    办理卡尔加里大学(本科)学历认证『微信171922772』calgary学位证成绩单使馆认证University of calgary Q.微信:171922772办理教育部国外学历学位认证海外大学毕 ...

  2. 电脑自动重启(Kernel-Power 41 (63) error)的一些解决办法

    查看是否有两个声卡驱动,如果有,尝试关闭其中一个. 可能是内存的问题,用memtest测试.如果有多于一个内存条,仅使用其中的一个试试. 更改电源设置,使机器工作在低耗状态. 更新所有驱动,尤其是主板 ...

  3. Android设备标识符的使用

    设备ID(DeviceId) 获取办法 android.telephony.TelephonyManager tm = (android.telephony.TelephonyManager) con ...

  4. 最强DE 战斗力 (nyoj 541)

    题解链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=541 几天前百度题解后用数学知识AC的,后来大牛说这是一道动态规划题. 网上的数学解题链接 ...

  5. Freeplane中的自动边线颜色功能

    今天我将电脑上的Freeplane从1.3.11升级到了1.5.18.发现新版本已经没有了1.3.11中的菜单选项Format → “Automatic edge color”.搜索了一下才发现,该功 ...

  6. 一个App从创意到最终上架到App Store里的整个过程是怎样的?

    一个App从创意到最终上架到App Store里的整个过程是怎样的? 制作App需要什么软件?应该看什么书?需要哪些设备?推到App Store里,需要注册什么网站?是否需要付费?需要什么证书之类的? ...

  7. 【安装】python3.4版安装与2.x共存问题

    首先,到官网去下载python3.x版,这里推荐3.4以上的版本,自带pip库,以后不用自己另外下载 3.4.4版: https://www.python.org/downloads/release/ ...

  8. 用CSS实现文本框尖角

    经常看到这样的尖角,以前不懂,以为都是用图片做出来的,后来惊奇的发现,原来很多都是用CSS做出来的,既美观又节省资源,真是两全其美啊! 那么,用CSS怎么实现这种效果呢?首先,来写一个简单的代码: & ...

  9. FZU 2240 Daxia & Suneast's problem

    博弈,$SG$函数,规律,线段树. 这个问题套路很明显,先找求出$SG$函数值是多少,然后异或起来,如果是$0$就后手赢,否则先手赢.修改操作和区间查询的话可以用线段树维护一下区间异或和. 数据那么大 ...

  10. css基础和心得(四)

     现在来说相对定位: 如果想为元素设置层模型中的相对定位,需要设置position:relaive(表示相对 定位),它通过left.right.top.bottom属性确定元素在正常文档流中便宜位 ...