JavaScript实现仅缓存上次结果的memoize函数无法读取缓存值问题
问题根因
你的代码缓存不生效的核心原因有两个:
- 缓存参数的变量
valOne、valTwo声明后从未被赋值更新,始终保持初始值undefined,参数比对逻辑几乎永远不会成立,自然无法命中缓存。你在else分支中只更新了lastResult,完全没有把当前传入的x1、x2存入缓存变量。 - 内层嵌套的
memoize函数属于多余写法,虽然不直接造成bug,但会让闭包逻辑变得冗余。
修正方案
只需要在每次执行原函数计算结果后,同步更新缓存的参数值,同时简化冗余的函数嵌套即可,修正后的完整代码如下:
function memoizeTransform(f) { // 缓存上一次的第一个参数、第二个参数、对应返回结果 let lastVal1, lastVal2, lastResult // 直接返回闭包函数,持有外层缓存变量的引用 return function(x1, x2) { // 比对当前参数和上一次缓存的参数是否完全一致 if (lastVal1 === x1 && lastVal2 === x2) { console.log("if statement") return lastResult } // 参数不一致,重新执行原函数计算 lastResult = f(x1, x2) // 核心修正:更新缓存的参数值,供下一次调用比对 lastVal1 = x1 lastVal2 = x2 return lastResult } }
效果验证
可以用如下测试代码验证逻辑:
// 测试函数,调用时会打印日志标识是否执行了原始逻辑 const calcSum = (a, b) => { console.log('执行原始计算逻辑') return a + b } const memoizedSum = memoizeTransform(calcSum) console.log(memoizedSum(1, 2)) // 输出:执行原始计算逻辑、3 console.log(memoizedSum(1, 2)) // 输出:if statement、3,命中缓存不执行原始逻辑 console.log(memoizedSum(3, 4)) // 输出:执行原始计算逻辑、7,参数变化重新计算 console.log(memoizedSum(3, 4)) // 输出:if statement、7,再次命中缓存
注:该实现符合当前练习的要求,仅缓存上一次调用的参数和结果,默认适配两个入参的场景,参数比对使用严格相等,引用类型参数需要引用地址完全一致才会命中缓存。
内容的提问来源于stack exchange,提问作者Armando Endzelis
相关产品推荐
相关产品推荐

