一、是什么

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

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

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

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. git合并代码操作-2022新项目

    自己做开发工作已经好几年,以前由于都是开发一些小项目,基本上也没拉什么分支进行开发,也没有涉及到合并代码的操作,因此自己对于如何合并代码还真没有实际地操作过.今天负责人突然交给我一个任务,让我去合并代 ...

  2. 基于python的多线程串口处理实例源码解析

    一 概念 1.简介 该源码可以让串口收发数据并行处理. 2.特性 使用了线程 使用了serial 使用了class 二 源码解析 1.串口读取固定数据函数: def uart_recv_header( ...

  3. Android 快速实现View的展开和收缩效果

    原文: Android 快速实现View的展开和收缩效果 - Stars-One的杂货小窝 看到一篇文章用到了一个布局的属性animateLayoutChanges就能实现展开和收缩效果,特意记录一下 ...

  4. 一些网络编程方面的总结,以及redis、memcache、nginx组件的一些介绍

    网络编程主要关注的一些问题 主要关注3个方面的问题 连接的建立 连接的断开 消息的发送和到达 连接的建立 主要分为两种情况:服务器处理接受客户端的连接:服务端作为客户端的连接第三方服务: //这是服务 ...

  5. Android编译系统

    一.概述 在 Android 7.0 之前,Android 编译系统使用 GNU Make 描述和shell来构建编译规则,模块定义都使用Android.mk进行定义,Android.mk的本质就是M ...

  6. 在Ubuntu14.04上安装qt5和qtcreator的 两种方式(源代码和xxxxx.run) 和我的感悟-------超级详细版

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

  7. Flutter Utils 全网最齐全的工具类

    FlutterUtils 目录介绍 01.事件通知bus工具类 02.颜色Color工具类 03.日期转化工具类 04.File文件工具类 05.Sql数据库工具类 06.Json转化工具类 07.L ...

  8. HDFS Balancer负载均衡器

    目录 1.背景 2.什么是平衡 2.1 每个DataNode的利用率计算 2.2 集群的利用率 2.3 平衡 3.hdfs balancer语法 4.运行一个简单的balance案例 4.1 设置平衡 ...

  9. go语言漏桶算法思路简单实现

    package main import ( "fmt" "time" ) // 桶 type LeakBucket struct { capacity int ...

  10. Failed to start component [StandardEngine[Catalina].StandardHost[localhost]] 记录

    jar包冲突 解决: <dependency>     <groupId>org.springframework.cloud</groupId>     <a ...