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

JavaScript中Memoize函数写法是否正确?求正确实现方案

你的JavaScript Memoize函数写法问题及修正方案

你的代码能实现基础的缓存效果,但存在几个关键问题,导致它在很多场景下无法正常工作:

  • 缓存key生成逻辑有缺陷:用a+""+b拼接字符串会导致参数组合冲突,比如memo(12, 3)和memo(1, 23)会生成相同的key "123",缓存结果会相互覆盖。
  • 与sum函数强耦合:memo函数只能为sum服务,无法复用给其他函数,通用性极差。
  • 全局缓存污染:cache是全局变量,若其他代码也使用同名变量或缓存逻辑,会互相干扰。
  • 假值缓存失效:如果sum返回0、false等假值,if(cache[key])会判断为假,导致重复计算,无法正确缓存这些结果。

正确的通用Memoize实现

function memoize(fn) {
  // 用闭包存储缓存,避免全局污染
  const cache = new Map();
  
  return function(...args) {
    // 序列化参数生成唯一key,支持多参数、基础类型参数
    const key = JSON.stringify(args);
    // 直接判断key是否存在,而非值是否为真
    if (cache.has(key)) {
      return cache.get(key);
    }
    const result = fn.apply(this, args);
    cache.set(key, result);
    return result;
  };
}

// 使用示例
function sum(a, b) {
  console.log(`Entering sum function ${a} & ${b}`);
  return a + b;
}

// 生成带缓存的sum函数
const memoizedSum = memoize(sum);

console.log(memoizedSum(1, 2));
console.log(memoizedSum(3, 2));
console.log(memoizedSum(3, 2)); // 直接返回缓存,不调用sum
console.log(memoizedSum(1, 2)); // 直接返回缓存,不调用sum
console.log(memoizedSum(5, 2));

补充说明

  • 这个实现是通用的,能给任意函数添加缓存能力,比如const memoizedPow = memoize(Math.pow)就能得到带缓存的幂运算函数。
  • 使用Map存储缓存,判断key是否存在的逻辑更可靠,避免了假值导致的缓存失效问题。
  • 若需要处理函数、Symbol等无法序列化的参数,可以自定义key生成逻辑(比如针对对象参数使用WeakMap),适配特定场景需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 03:50:34