闭包实现备忘模式
利用闭包实现备忘模式
function memorzie(fn){
let cache = {}
//创建复杂函数缓存对象
return function(...args){
//将处理的复杂函数的参数转化为数组
let key = JSON.stringify(args)
//将数组转化为字符串
let cacheKeys = Object.keys(cache)
//获取当前缓存对象的键
if(cacheKeys.length >= 20){
let firstKey = cacheKeys[0]
delete cache[firstKey]
}
//如果缓存对象过大就清除掉一部分键值对
return cache[key] || (cache[key] = fn.apply(fn,args))
//如果缓存对象的键中当前调用函数的参数就直接返回,否则进行计算
}
}
function add(a){
return a+1
}
//复杂函数
const adder = new memorzie(add)
adder(1345678)
adder(13456789)
adder(23456789)
adder(23456789)
稍微解释一下:
备忘函数中用 JSON.stringify
把传给 adder
函数的参数序列化成字符串,把它当做 cache
的索引,将 add
函数运行的结果当做索引的值传递给 cache
,这样 adder
运行的时候如果传递的参数之前传递过,那么就返回缓存好的计算结果,不用再计算了,如果传递的参数没计算过,则计算并缓存 fn.apply(fn, args)
,再返回计算的结果。
当然这里的实现如果要实际应用的话,还需要继续改进一下,比如:
- 缓存不可以永远扩张下去,这样太耗费内存资源,我们可以只缓存最新传入的 n 个;
- 在浏览器中使用的时候,我们可以借助浏览器的持久化手段,来进行缓存的持久化,比如 cookie、localStorage 等;
这里的复杂计算函数可以是过去的某个状态,比如对某个目标的操作,这样把过去的状态缓存起来,方便地进行状态回退。
复杂计算函数也可以是一个返回时间比较慢的异步操作,这样如果把结果缓存起来,下次就可以直接从本地获取,而不是重新进行异步请求。