javascript基础二十六:JavaScript中如何实现函数缓存?有哪些应用场景?

news2024/10/7 14:31:33

在这里插入图片描述
一、是什么

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

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

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

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 如何返回另一个函数 bar,baz 现在持有对 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中

三、应用场景

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/609569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux邮件发送教程:深入了解mail命令

前言 大家好,又见面了,我是沐风晓月,本文是专栏【linux基本功-基础命令实战】的第59篇文章。 专栏地址:[linux基本功-基础命令专栏] , 此专栏是沐风晓月对Linux常用命令的汇总,希望能够加深自己的印象&am…

Java进行公众号开发的常见使用场景及解决方案

Java进行公众号开发的常见使用场景解决方案 文章简介 本文总结了本人在开发过程中遇到的有关于微信开发的诸多常见功能,这些问题在网上找都是零散的回答,所以再此总结一下,方便后续开发。如果有错误之处,还望批评指出&#xff0…

使用Kaggle GPU资源免费体验Stable Diffusion开源项目

使用Kaggle GPU资源免费体验Stable Diffusion开源项目 前言相关介绍Stable Diffusion Kaggle开源项目编辑并复制项目运行项目打开网址,即可体验 参考 前言 由于本人水平有限,难免出现错漏,敬请批评改正。更多精彩内容,可点击进入Y…

javascript基础二十五:说说你对函数式编程的理解?优缺点?

一、是什么 函数式编程是一种"编程范式"(programming paradigm),一种编写程序的方法论 主要的编程范式有三种:命令式编程,声明式编程和函数式编程 相比命令式编程,函数式编程更加强调程序执行…

C SS复习笔记

1.img标签 img的src属性是图片显示不出来时显示的文字 ing的title属性是光标放到图片上,提示的文字 2.a标签 a标签的target属性表示打开窗口的方式,默认的值是_self表示当前窗口的打开页面,_blank表示新窗口打开页面。 a标签的href链接分…

2023.06.04 学习周报

文章目录 摘要文献阅读1.题目2.背景3.方案4.本文贡献5.模型5.1 图注意力形式5.2 superGAT 6.实验7.结论 有限元数学建模深度学习1.高斯扩散2.原理 总结 摘要 This week, I read a computer science about GNN. At present, the attention mechanism of graph neural network i…

Go Web下GORM框架使用(二)

〇、前言 本文将会写一个前后端分离的的小项目,本文将会只实现后端。 一、定义全局变量与模型 本文需要一个数据库,因此将这个数据库定义为全局变量将会非常轻松。 var (DB *gorm.DB )type Todo struct {ID int json:"id"Title s…

【C#图解教程】第六章 方法(下)

输出参数 函数的输出只有返回值有时不太够,此时需要用到输出参数,用修饰词out声明 输出参数的要求与引用参数类似,需要是变量,此外,输出参数也是实参的别名,指向堆中同一对象。 输出参数与引用参数的不同在…

【实用篇】Elasticsearch03

文章目录 分布式搜索引擎031.数据聚合1.1.聚合的种类1.2.DSL实现聚合1.2.1.Bucket聚合语法1.2.2.聚合结果排序1.2.3.限定聚合范围1.2.4.Metric聚合语法1.2.5.小结 1.3.RestAPI实现聚合1.3.1.API语法1.3.2.业务需求1.3.3.业务实现 2.自动补全2.1.拼音分词器2.2.自定义分词器2.3.…

【人工智能】— Support Vector Machines 支持向量机

【人工智能】— Support Vector Machines 支持向量机 支持向量机概述支持向量机支持向量机原理介绍分类间距(Classification Margin) 支持向量机概述 找到使间隔最大化的超平面>B1比B2更好 支持向量机 研究起因:如何找到最优的切分面 分…

制作酷炫可视化大屏利器--分享10种比较流行的开源免费的图表库

在开发可视化项目的过程中往往涉及到可视化图表, 多酷炫的报表, 大屏, 都用了非常多的图表, 接下来我和大家分享一些比较流行的开源免费的图表库. 分享10种比较流行的开源免费的图表库 1,Frappe Charts2,Recharts3,Protovis4,dygr…

Docker快速入门(分分钟钟就能上手)

Docker的思想 集装箱:会将所有需要的内容放到不同的集装箱中,谁需要这些环境就直接拿到这个集装箱就可以了。标准化: 运输的标准化:Docker有一个码头,所有上传的集装箱都放在了这个码头上,当谁需要某一个环…

设计模式-01.设计思想

设计思想 此系列文章非本人原创,是学习笔记。 下面讲一些常见的设计思想 基于接口而非实现编程 这个原则非常重要,是一种非常有效的提高代码质量的手段,在平时的开发中特别经常被用到。 如何解读原则中的“接口”二字? “基于…

python面向对象操作1(速通版)

目录 一、高阶函数 1.lambda函数 2.lambda函数注意事项 3.map用法 4.map和lambda函数配合 二、reduce函数 1.reduce基本应用 2.reduce和匿名函数配合 三、filter()函数 1.简单用法 2.高阶应用 四、列表排列方法(key和lambda问题) 1.正常排序…

Node服务器和常见模块

1 Node服务器开发 2 fs模块-文件系统 3 event模块-事件处理 4 认识二进制和buffer 5 Buffer的创建方式 6 Buffer的源码解析 node 的fs模块操作: 这里主要讲node如何进行读取文件,操作文件。服务器该有的操作node都有。 node的fs读取文本文件内容的d…

自定义starter

第一步、创建 xxx-spring-boot-starter 的spring Initializr模块 第二步、删除不需要的内容&#xff08;启动类、除下面spring-boot-starter的其它依赖&#xff0c;maven编译插件&#xff09; <dependency><groupId>org.springframework.boot</groupId><…

linux理解软硬链接

软硬连接 在linux下面链接文件有两种&#xff0c;一种是类似window的快捷方式功能的文件&#xff0c;可以让你快速链接到目标文件&#xff08;或目录&#xff09;&#xff0c;叫做软链接&#xff0c;另一种则是通过文件系统的inode链接来产生新的文件名&#xff0c;而不是产生…

Linux 常用开发工具(yum、vim)

绪论 耐心是一切聪明才智的基础。—— 柏拉图。本章进入到Linux下的一些常用的工具&#xff0c;这些工具能帮助我们去更好的使用Linux操作系统。 话不多说安全带系好&#xff0c;发车啦&#xff08;建议电脑观看&#xff09;。 附&#xff1a;红色&#xff0c;部分为重点部分&a…

[MAUI程序设计] 用Handler实现自定义跨平台控件

文章目录 Handler与Xamarin.Forms实现的区别为什么要用Handler代替Renderer解耦生命周期管理更细粒度的控制 用Effect来实现呢&#xff1f;自定义手势监听控件在各平台上实现TouchRecognizeriOS中的实现Android中的实现Windows中的实现 创建控件使用控件最终效果项目地址 今天来…

使用 Kubeadm 和 CRI-O 在 Rocky Linux 8 上安装 Kubernetes 集群

在 Rocky Linux 8 上安装 Kubernetes 集群。毫无疑问&#xff0c;Kubernetes 将继续改变我们大规模部署和管理业务应用程序的方式。无论用于部署应用程序的模型是手动还是通过 CI/CD 管道&#xff0c;Kubernetes 仍然是处理编排、管理和扩展应用程序的最佳选择。 对于那些不知…