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

需要注意的是,记忆只是一种编程技巧,本质上是牺牲算法的空间复杂度以换取更优的时间复杂度,在客户端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. python下实现汉诺塔

    汉诺塔是印度一个古老传说的益智玩具.汉诺塔的移动也可以看做是递归函数. 我们对柱子编号为a, b, c,将所有圆盘从a移到c可以描述为: 如果a只有一个圆盘,可以直接移动到c: 如果a有N个圆盘,可以 ...

  2. openstack私有云布署实践【8.1 身份认证keystone的API创建(科兴环境)】

    其中一台controller上面加入环境变量,我选kxcontroller1,关注的是endpoint的名称不一样,其它创建的参数与测试环境一致 export OS_TOKEN=venicchina ...

  3. shell 读取文件

    #!/bin/bash content=`cat test.txt` echo "begin" for i in $content do echo $i done 读取前10行 t ...

  4. 网页视频下载牛逼工具,支持各种格式转换,比如腾讯视频格式qlv转mp4

    这种思路真是创新,原文地址:http://jingyan.baidu.com/article/5225f26b03f047e6fb090860.html 软件工具名字:维棠下载. 上图: 1:搜索视频 ...

  5. readonly属性在各浏览器中的区别

    有个项目需求是正常显示时为只读,不可修改: 点击修改按钮后,可修改表单元素. 首先想到的是readonly属性,其用于规定输入字段为只读,不能修改.在javascript中消除readonly值,可将 ...

  6. android 界面布局

    一.LinearLayout LinearLayout 又称作线性布局,是一种非常常用的布局,它所包含的控件在线性方向上依次排列. android:orientation="horizont ...

  7. Android设置窗体Activity背景透明

    背景透明 style.xml <item name="android:windowBackground">@color/transparent</item> ...

  8. hdu1036

    #include<stdio.h>int main(){ int n; double d; int num; char h,m1,m2,s1,s2; scanf("%d" ...

  9. Windows端口转发

    1. PortTunnel 2. windows 自带的 netsh -----windows下也有一个小工具:portforward.exe,图形界面容易操作,个人平常使用可以,但是也没有办法实现与 ...

  10. db2 备份还原

    一.导入导出 ixf: db2 export to /tmp/xxx.csv of ixf lobs to . xml to . modified by codepage=1208 "sel ...