JavaScript memoize函数实现求助:多测试未通过,需完善功能
修正JavaScript memoize函数实现问题
原代码存在的核心问题
- 未支持需求中的可选
resolver参数,无法自定义缓存键生成规则 - 缓存命中判断逻辑错误:用
memo.has(args)判断缓存是否存在,但实际存储的键是JSON.stringify(args),而args是每次调用生成的新数组,Map的键采用严格相等比较,导致永远无法命中缓存 - 未给返回的memoized函数添加
clear()、delete(...args)、has(...args)三个必需方法,直接导致相关测试用例失败 - 缓存写入逻辑冗余:先执行
set再get,可以简化为判断不存在时写入,直接返回缓存值
修正后的完整实现
function memoize(cb, resolver) { const memo = new Map(); // 统一生成缓存键的工具函数 const getCacheKey = (...args) => { return typeof resolver === 'function' ? resolver(...args) : JSON.stringify(args); }; // 核心memoized函数 const memoizedFn = function (...args) { const key = getCacheKey(...args); if (!memo.has(key)) { memo.set(key, cb(...args)); } return memo.get(key); }; // 实现clear方法:清空所有缓存 memoizedFn.clear = () => memo.clear(); // 实现delete方法:删除指定参数对应的缓存项 memoizedFn.delete = (...args) => { const key = getCacheKey(...args); return memo.delete(key); }; // 实现has方法:判断指定参数的缓存项是否存在 memoizedFn.has = (...args) => { const key = getCacheKey(...args); return memo.has(key); }; return memoizedFn; }
关键改进点说明
- 支持自定义resolver:通过
getCacheKey函数判断是否传入了resolver,存在则使用其返回值作为缓存键(支持任意类型),否则使用参数数组的JSON字符串,完全符合需求规则 - 修复缓存命中逻辑:使用生成的缓存键去Map中判断和存取,确保缓存能正确命中
- 添加必需的辅助方法:
clear():直接调用Map原生的clear方法清空所有缓存delete(...args):根据传入参数生成对应键,删除Map中的对应缓存项has(...args):根据参数生成键,检查Map中是否存在该缓存项
- 简化缓存写入逻辑:仅在缓存不存在时执行原回调并写入缓存,减少不必要的Map操作
验证测试用例
现在这个实现可以通过所有给出的测试用例:
- 无参回调只会被调用一次
- 单参数回调的缓存命中逻辑正常
has()方法能正确判断缓存项的存在状态
内容的提问来源于stack exchange,提问作者Vitamin
相关产品推荐
相关产品推荐

