一、是什么

函数缓存,就是将函数运算过的结果进行缓存

本质上就是用空间(缓存存储)换时间(计算过程)

常用于缓存数据计算结果和缓存对象

const add = (a,b) => a+b;
const calc = memoize(add); // 函数缓存
calc(10,20);// 30
calc(10,20);// 30 缓存

缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能够更快地得到处理

二、如何实现

实现函数缓存主要依靠闭包、柯里化、高阶函数,这里再简单复习下:

闭包

闭包可以理解成,函数 + 函数体内可访问的变量总和

(function() {
    var a = 1;
    function add() {
        const b = 2
        let sum = b + a
        console.log(sum); // 3
    }
    add()
})()

add函数本身,以及其内部可访问的变量,即 a = 1,这两个组合在⼀起就形成了闭包

柯里化

把接受多个参数的函数转换成接受一个单一参数的函数

// 非函数柯里化
var add = function (x,y) {
    return x+y;
}
add(3,4) //7

// 函数柯里化
var add2 = function (x) {
    //**返回函数**
    return function (y) {
        return x+y;
    }
}
add2(3)(4) //7

将一个二元函数拆分成两个一元函数

高阶函数

通过接收其他函数作为参数或返回其他函数的函数

function foo(){
  var a = 2;

  function bar() {
    console.log(a);
  }
  return bar;
}
var baz = foo();
baz();//2

函数 foo 如何返回另一个函数 barbaz 现在持有对 foo 中定义的bar 函数的引用。由于闭包特性,a的值能够得到

下面再看看如何实现函数缓存,实现原理也很简单,把参数和对应的结果数据存在一个对象中,调用时判断参数对应的数据是否存在,存在就返回对应的结果数据,否则就返回计算结果

如下所示

const memoize = function (func, content) {
  let cache = Object.create(null)
  content = content || this
  return (...key) => {
    if (!cache[key]) {
      cache[key] = func.apply(content, key)
    }
    return cache[key]
  }
}

调用方式也很简单

const calc = memoize(add);
const num1 = calc(100,200)
const num2 = calc(100,200) // 缓存得到的结果

过程分析:

  • 在当前函数作用域定义了一个空对象,用于缓存运行结果
  • 运用柯里化返回一个函数,返回的函数由于闭包特性,可以访问到cache
  • 然后判断输入参数是不是在cache的中。如果已经存在,直接返回cache的内容,如果没有存在,使用函数func对输入参数求值,然后把结果存储在cache

三、应用场景

虽然使用缓存效率是非常高的,但并不是所有场景都适用,因此千万不要极端的将所有函数都添加缓存

以下几种情况下,适合使用缓存:

  • 对于昂贵的函数调用,执行复杂计算的函数
  • 对于具有有限且高度重复输入范围的函数
  • 对于具有重复输入值的递归函数
  • 对于纯函数,即每次使用特定输入调用时返回相同输出的函数

JavaScript中如何实现函数缓存?有哪些应用场景?的更多相关文章

  1. 借助JavaScript中的时间函数改变Html中Table边框的颜色

    借助JavaScript中的时间函数改变Html中Table边框的颜色 <html> <head> <meta http-equiv="Content-Type ...

  2. 前端学习 第二弹: JavaScript中的一些函数与对象(1)

    前端学习 第二弹: JavaScript中的一些函数与对象(1) 1.apply与call函数 每个函数都包含两个非继承而来的方法:apply()和call(). 他们的用途相同,都是在特定的作用域中 ...

  3. 理解和使用 JavaScript 中的回调函数

    理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报  分类: JavaScript(4)    目录( ...

  4. JavaScript中变量和函数声明的提升

    现象: 1.在JavaScript中变量和函数的声明会提升到最顶部执行. 2.函数的提升高于变量的提升. 3.函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找. 4.匿名函数不会提升. ...

  5. javascript中使用md5函数

    javascript中使用md5函数 这对于js来讲本来是没有的,现在可以自己定义一个md5的函数,达到加密效果. var hexcase = 0; function hex_md5(a) { if ...

  6. 在 JavaScript 中使用构造器函数模拟类

    今天,我们要讲的是在 JavaScript 中使用构造器函数(construcor function)模拟类. 构造器函数简介 你可以使用 ES6 的 class 关键字来实现类,不过我建议你使用传统 ...

  7. 来一轮带注释的demo,彻底搞懂javascript中的replace函数

    javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...

  8. 理解javascript中的回调函数(callback)【转】

    在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...

  9. JavaScript 中的回调函数

    原文:http://javascriptissexy.com/ 翻译:http://blog.csdn.net/luoweifu/article/details/41466537 [建议阅读原文,以下 ...

  10. JavaScript中字符串分割函数split用法实例

    这篇文章主要介绍了JavaScript中字符串分割函数split用法,实例分析了javascript中split函数操作字符串的技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了JavaSc ...

随机推荐

  1. A left join B B表有多条记录,max(create_time)取最新一条

    例如:A表合同表t_contract  B表合同审核表t_contract_audit.两个表根据contract_id关联.且一条合同有多条审核记录.求:A.合同状态.B.最新审核记录结果. 简单: ...

  2. git cherry-pick 摘樱桃 vscode

    git cherry-pick -n b2e9bf7530ce42910a5be99c358fa8c7ab6af507 -n 就是临时到暂存里面 SHA 可以为多个 逗号拼接

  3. windows10 使用gcc编译生成可执行文件exe实例解析

    一 操作步骤 1.生成可执行程序 cd xxx # 先进入源程序所在的目录 gcc hello.cpp # 一次性编译,windows系统生成a.exe文件,Linux系统生成a.out文件 gcc ...

  4. wav 格式音频文件生成例子

    wavfile is a simple sound library for use in CSE 20211. This library allows you to generate arbitrar ...

  5. GdbServer和libuuid移植到HISI3520d

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  6. 关于编写GUI程序我自己的一些理解

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文发布于 2014-10-12 14:51:31 ...

  7. 人人都是艺术家!AI工具Doodly让潦草手绘变精美画作

    AI绘画界太卷了,一天一个新东西,不久前刚给大家介绍了可以一秒出图的SDXL-Turbo,今天来聊一聊另一位重磅选手Doodly 有用过Stable Diffuison的小伙伴都知道,想要生成一张高质 ...

  8. 【Django】如何在类视图、普通视图单独不做CSRF校验

    一.背景 在某些特定场合下,需要局部禁用CSRF校验,比如,期望整个项目都启用CSRF,但是中途遇到某一两个视图要去掉这个校验 二.方案 1.如果你写Django的路由用的类视图,那么需要这样写 在 ...

  9. VR虚拟现实技术下的汽车展厅:优劣势及运作方式

    虚拟现实汽车展厅其实是一种在线商店,可让客户在模拟环境中体验产品.这对无法亲自到店的人很有帮助.客户可以使用虚拟现实耳机来探索可用的不同型号和颜色.这可以帮助他们就购买哪辆汽车做出更明智的决定.虚拟现 ...

  10. 聚焦“云XR如何赋能元宇宙”,3DCAT实时云渲染首届行业生态合作交流会成功举办

    2021年12月17日下午,由深圳市瑞云科技有限公司主办,深圳市虚拟现实产业联合会协办的云XR如何赋能元宇宙--3DCAT实时云渲染首届行业生态合作交流会圆满落幕.此次活动围绕 "云XR如何 ...