信息发布→ 登录 注册 退出

javascript Memoization是什么_如何优化函数性能

发布时间:2025-12-25

点击量:
Memoization 是通过缓存函数结果避免重复计算的优化技术,适用于纯函数;用 Map 缓存、需确保纯性、注意内存清理;示例实现用 JSON.stringify 生成 key。

Memoization 是一种通过缓存函数已计算结果来避免重复执行的优化技术,特别适合纯函数(相同输入总返回相同输出、无副作用)。

核心原理:用空间换时间

函数首次被调用时,把输入参数作为 key,返回值作为 value 存入缓存(通常是 JavaScript 对象或 Map);后续相同输入直接从缓存取值,跳过实际运算。

  • 缓存结构推荐用 Map(支持任意类型 key,如对象、函数、Symbol)而非普通对象(只适合字符串/数字 key)
  • 必须确保函数是纯的,否则缓存可能返回过期或错误结果
  • 注意内存占用——长期运行的程序需考虑缓存清理策略(如 LRU、TTL 或手动清除)

手写一个基础 memoize 工具函数

以下是一个轻量、通用的实现:

function memoize(fn) {
  const cache = new Map();
  return function(...args) {
    const key = JSON.stringify(args); // 简单序列化(仅适用于可 JSON 化参数)
    if (cache.has(key)) {
      return cache.get(key);
    }
    const result = fn.apply(this, args);
    cache.set(key, result);
    return result;
  };
}

使用示例:

const fibonacci = memoize(n => n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2));
fibonacci(35); // 首次较慢,但后续调用极快

进阶:处理复杂参数与上下文

JSON.stringify 无法正确处理函数、undefined、Date、RegExp、循环引用等。生产环境建议:

  • fast-deep-equal lodash.isEqual 实现深度参数比对(配合自定义 key 生成)
  • 若函数依赖 this,需在闭包中绑定上下文或使用 fn.call(this, ...args)
  • 可扩展支持 options:maxSize(限制缓存条目数)、ttl(过期时间)、cacheKey(自定义 key 生成函数)

何时不该用 memoization?

不是所有函数都适合加 memo:

  • 输入组合极少,或几乎不会重复调用(缓存反而增加开销)
  • 函数本身极快(如简单加法),缓存查找成本可能高于重新计算
  • 参数含不可序列化值且无可靠 key 生成方式
  • 函数有副作用(如发请求、修改 DOM),缓存会掩盖行为,破坏预期逻辑
标签:# javascript  # java  # js  # json  # app  # 工具  # 内存占用  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!