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

需要注意的是,记忆只是一种编程技巧,本质上是牺牲算法的空间复杂度以换取更优的时间复杂度,在客户端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. hibernate-部分字段查询方案

    hibernate的延迟加载与本列记录不一样,延迟加载正常一般用于关联字段,或者大型字段使用. 本列的情况主要用于,某一张表有几十甚至上百个字段,例如财务报表等.但是在使用某些场景是却大多只是用其10 ...

  2. CodeForces 721C Journey

    $dp$,拓扑排序. 记$dp[i][j]$表示走到节点$i$,走过了$j$个点的最小时间,然后就可以递推了.要注意的是节点$1$的入度一开始不一定等于$0$. #pragma comment(lin ...

  3. CodeForces 718C Sasha and Array

    线段树. 线段树维护区间矩阵和,操作都是最简单的线段树.$lazy$标记不要记录乘了几次,直接记录乘了几次之后的矩阵就可以了,不然每次下传的时候再算一遍时间复杂度会提高. #pragma commen ...

  4. 借助OpenOffice实现office转pdf(Java)的.exe小程序

    原料:OpenOffice4.1.2(之所以选OpenOffice是因为可以跨平台,下载后直接安装),jodconverter-core-3.0-beta-4-dist.zip(可以搜博客园),Exe ...

  5. git commit

    使用 git add 命令将想要快照的内容写入缓存区, 而执行 git commit 将缓存区内容添加到仓库中. Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步需要配置用户名和邮箱地 ...

  6. 遍历HashMap的最佳方式

    public static void printMap(Map mp) { Iterator it = mp.entrySet().iterator(); while (it.hasNext()) { ...

  7. Intellj idea 安装JUnit

    1.file-Settings-Plugins-Browse repositories-HTTP Proxy Settings将No proxy改成Auto-detect proxy settings ...

  8. WindowsServer2012 R2 64位中文标准版(IIS8.5)下手动搭建PHP环境详细图文教程(二)安装IIS8.5

    //来源:http://www.imaoye.com/Technology/WindowsServer2012R264IIS85.html 阿里云服务器ECS Windows Server 2012 ...

  9. Kmplayer播放器 绿色免安装版 2016 中文版

    软件名称: Kmplayer播放器 绿色免安装版 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 42.8MB 图片预览: 软件简介: Kmplayer播放 ...

  10. 在VMware上安装CentOS -7步骤详解

    在VMware上安装CentOS -7 一.下载好VMware虚拟机 二.准备好CentOS的镜像文件 在这里安装之前博主都已准备好了. 废话就少啰嗦啦!现在开始安装步骤了 1.首先打开VMware创 ...