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

JS调用memoize记忆化函数返回函数而非计算结果的问题

问题原因
  • getMaxValue的定义写法错误:当前写法const getMaxValue = (config) => memoize(_getMaxValue)是一个接收config参数、每次调用都会返回新的memoize包装函数的普通函数,调用getMaxValue(config)时根本没有执行包装后的计算逻辑,直接返回了memoize生成的内部闭包函数,因此打印结果是函数块。对比正常工作的add可以发现差异:add是直接执行memoize(_add)拿到包装后的计算函数,调用时传参就会触发计算,这才是memoize的正确用法。
  • 现有memoize实现逻辑不通用:内部硬编码了args.reduce((acc, curr) => fn(acc, curr), 0)的调用逻辑,仅适配累加类多参数函数,完全不支持_getMaxValue这类单参数、不需要归约计算的函数。就算修正了getMaxValue的定义,这段逻辑也会把初始值0作为第一个参数传入原函数,导致入参不符合预期,计算结果错误。
修正后代码
const config = {
    14340: 1195,
    15774: 1226,
    17208: 1257,
    18642: 1288,
    20076: 1319
}

const memoize = (fn) => {
    let cache = {}
    return (...args) => {
        // 用JSON.stringify处理参数,避免对象类型参数生成错误缓存key
        let cacheKey = args.map(n => JSON.stringify(n)).join('+')
        if (cacheKey in cache) {
            return cache[cacheKey]
        }
        // 直接透传所有参数给原函数,不硬编码归约逻辑,适配任意入参形式
        const result = fn.apply(this, args)
        cache[cacheKey] = result
        return result
    }
}

function _getMaxValue(config) {
    const keys = Object.keys(config)
        .map((k) => parseInt(k, 10))
        .sort();
    return config[keys[keys.length - 1].toString()];
}

// 移除外层多余的箭头函数包装,直接赋值memoize返回的包装函数
const getMaxValue = memoize(_getMaxValue)

const _add = (a, b) => {
    return a + b
}
const add = memoize(_add)

console.log(getMaxValue(config)) // 输出1319,符合预期
console.log(add(1, 2)) // 输出3,正常运行
修改说明
  • 移除getMaxValue外层多余的箭头函数包装,和add的定义保持一致,调用时传入参数即可直接触发计算逻辑
  • 去掉memoize内部硬编码的reduce归约逻辑,改用fn.apply(this, args)透传所有入参,适配任意参数形式的工具方法
  • 优化缓存key生成逻辑,用JSON.stringify处理参数,避免对象、引用类型参数转字符串时出现[object Object]导致的缓存key冲突问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:27:21