利用闭包的特点来实现一个简单的缓存

备忘模式就是应用闭包的特点的一个典型应用。比如下面函数:

当多次执行 add() 时,每次得到的结果都是重新计算得到的,如果是开销很大的计算操作的话就比较消耗性能了。这里可以对已经计算过的输入做一个缓存。

javascript 复制代码
        function add(a) {
            return a+1;
        }

所以这里可以利用闭包的特点来实现一个简单的缓存,在函数内部用一个对象存储输入的参数,如果下次再输入相同的参数,那就比较一下对象的属性。如果有缓存,就直接把值从这个对象里面取出来。

实现代码如下:

备忘函数中用 JSON.stringify 把传给 adder 函数的参数序列化成字符串,把它当做 cache 的索引,将 add 函数运行的结果当做索引的值传递给 cache。

这样 adder 运行的时候如果传递的参数之前传递过,那么就返回缓存好的计算结果,不用再计算了,如果传递的参数没计算过,则计算并缓存 fn.apply(fn, args),再返回计算的结果。

javascript 复制代码
      function memorize(fn) {
        let cache = {};
        return function(...args) {
            let key = JSON.stringify(args)
            if (!(key in cache)) {
                console.log('需要计算')
                cache[key] = fn.apply(fn, args)
            }
            return cache[key]
        }
      }

      function add(a) {
        return a + 1
      }

      var adder = memorize(add)
      console.log(adder(1)); // 2
      console.log(adder(1)); // 2
      console.log(adder(2)); // 3
      console.log(adder(3)); // 4
      console.log(adder(1)); // 2
相关推荐
github_is_geeksKai13 分钟前
浏览器端文件处理的边界:PDF 面单、GPX 隐私与 EPUB 修复
前端
deli0071 小时前
从一句反馈到一次升级:Mystudy 的自进化实践
前端
FungLeo2 小时前
成为全栈·Vue 管理后台篇·用 fetch 建一层可控的请求内核
前端·javascript·vue.js·http·fetch·formdata·接口封装
FungLeo3 小时前
成为全栈·Vue 管理后台篇·Vue Router如何守住多角色后台边界
前端·javascript·vue.js·rbac·vue router·路由守卫·前端权限
FungLeo4 小时前
成为全栈·Vue 管理后台篇·分页只显示第一页:从接口total 定位到前端修复
前端·vue.js·状态模式·分页·naive ui·服务端分页·前端问题排查
时间的拾荒人4 小时前
Redis 集合类型详解:Set 与 Zset
redis·缓存·面试
ZhengEnCi4 小时前
苹果滑动为什么有「肉感」:橡皮筋越界阻尼与弹簧动画的物理原理
前端
Moment4 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源
L1mbo4 小时前
Lite模式 缓解微信开发者工具卡顿,附 uni-app 实践方案
前端·微信小程序
FungLeo4 小时前
成为全栈·Vue管理后台篇·仪表盘不是几张卡片:组合统计接口与角色视图
前端·javascript·vue.js·rbac·仪表盘·管理后台·tanstack query