You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

关键改进点说明

  1. 支持自定义resolver:通过getCacheKey函数判断是否传入了resolver,存在则使用其返回值作为缓存键(支持任意类型),否则使用参数数组的JSON字符串,完全符合需求规则
  2. 修复缓存命中逻辑:使用生成的缓存键去Map中判断和存取,确保缓存能正确命中
  3. 添加必需的辅助方法:
    • clear():直接调用Map原生的clear方法清空所有缓存
    • delete(...args):根据传入参数生成对应键,删除Map中的对应缓存项
    • has(...args):根据参数生成键,检查Map中是否存在该缓存项
  4. 简化缓存写入逻辑:仅在缓存不存在时执行原回调并写入缓存,减少不必要的Map操作

验证测试用例

现在这个实现可以通过所有给出的测试用例:

  • 无参回调只会被调用一次
  • 单参数回调的缓存命中逻辑正常
  • has()方法能正确判断缓存项的存在状态

内容的提问来源于stack exchange,提问作者Vitamin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:55:18