JavaScript缓存函数的核心是用对象或Map缓存参数组合与结果,相同输入直接返回缓存值;适用于纯函数如斐波那契、阶乘等;基础版支持单基本类型参数,增强版用JSON.stringify处理多参但有局限,生产级推荐Map加自定义键生成器,并注意纯函数约束、内存泄漏和异步缓存等问题。

JavaScript中实现缓存函数(即记忆化,Memoization)的核心思路是:**用对象或Map缓存已计算过的参数组合与对应结果,下次遇到相同输入时直接返回缓存值,跳过重复计算**。它特别适合纯函数(相同输入总得相同输出、无副作用),比如斐波那契、阶乘、解析复杂JSON结构等场景。
基础版:单参数 + 字符串键
最简单的情况是函数只接收一个基本类型参数(如 number、string)。这时可直接用参数作键:
function memoize(fn) { const cache = {}; return function(arg) { if (arg in cache) { return cache[arg]; } const result = fn(arg); cache[arg] = result; return result; };}// 使用示例const fib = memoize(n => n <= 1 ? n : fib(n - 1) + fib(n - 2));console.log(fib(10)); // 快速返回 55
✅ 简单直观,适合数字/字符串等可安全作为对象属性名的参数❌ 不支持对象、数组、undefined、Symbol 等无法稳定转为字符串的值(例如 {a:1} 和 {a:1} 会变成相同字符串 "[object Object]")
增强版:多参数 + JSON.stringify(慎用)
多个参数时,常用 JSON.stringify([...arguments]) 生成唯一键:
function memoizeMulti(fn) { const cache = new Map(); return function(...args) { const key = JSON.stringify(args); if (cache.has(key)) { return cache.get(key); } const result = fn(...args); cache.set(key, result); return result; };}
✅ 支持任意数量参数,对普通对象/数组也能工作(只要可序列化)❌ JSON.stringify 有局限:忽略函数、undefined、Symbol;不区分 {a:1,b:2} 和 {b:2,a:1}(属性顺序影响键);性能开销略大;不能处理循环引用
生产级:使用 Map + 自定义键生成器
更健壮的做法是用 Map 存储,并为参数设计稳定、可比较的键。常见策略包括:
立即学习“Java免费学习笔记(深入)”;
对每个参数用 typeof 判断后分别处理:基本类型直接用,对象用 Object.is 或 === 比较引用,或用弱映射(WeakMap)缓存对象实例使用现成库如 lodash.memoize(支持自定义 resolver 函数)手动实现带参数归一化的版本(例如把对象参数转为排序后的键字符串,或用结构化克隆+哈希,但成本高)
简化的安全多参版(适用于无嵌套对象的场景):
function memoizeSafe(fn) { const cache = new Map(); return function(...args) { // 用参数类型+值拼接成唯一键(避免 JSON 的坑) const key = args.map(a => typeof a === 'object' && a !== null ? `${typeof a}_${a.constructor.name}_${Object.keys(a).sort().join(',')}` : `${typeof a}_${String(a)}` ).join('|');if (cache.has(key)) { return cache.get(key);}const result = fn(...args);cache.set(key, result);return result;
};}
注意事项与边界
记忆化不是万能的,用前需确认:
函数必须是纯函数——不能依赖外部变量、不能修改全局状态、不能有随机性注意内存泄漏:缓存无限增长?建议加最大容量限制或 LRU 策略(可用 lru-cache 或自己封装 Map + 链表)异步函数需配合 Promise 缓存(缓存的是 Promise 实例本身,不是最终值,避免重复发起请求)箭头函数、this 绑定:memoize 包裹后会丢失原始 this,如需保留,应在闭包内显式绑定
基本上就这些。记住核心:缓存是空间换时间,关键在“键要唯一且稳定”,其余都是围绕它做取舍。
以上就是JavaScript中如何实现缓存函数_记忆化技术的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1542687.html
微信扫一扫
支付宝扫一扫