闭包实现的缓存斐波那契函数通过内部私有cache(对象或Map)避免重复计算,将时间复杂度从O(2ⁿ)降至O(n);推荐Map以支持任意键类型并避免隐式转换,配合输入校验提升健壮性。

用闭包实现带缓存的斐波那契数列,核心是把缓存对象(如 Map 或普通对象)封闭在函数作用域内,避免外部干扰,同时复用已计算结果,把指数级时间复杂度降到线性。
缓存结构选对象还是 Map?
推荐用普通对象或 Map 都可以,但要注意键类型:
- 用对象时,键只能是字符串,
fib(0)和fib('0')会命中同一项,适合非负整数输入 - 用
Map更严谨,支持任意类型键(比如未来扩展负数、小数),且不会隐式转换
基础闭包缓存版本(对象存储)
返回一个函数,内部维护 cache 对象,首次调用存值,后续直接返回:
const fib = (function() {
const cache = { 0: 0, 1: 1 };
return function(n) {
if (n in cache) return cache[n];
cache[n] = fib(n - 1) + fib(n - 2);
return cache[n];
};
})();
注意:这里用的是自执行函数表达式(IIFE),cache 只初始化一次,所有调用共享同一份缓存。
立即学习“Java免费学习笔记(深入)”;
更健壮的版本(Map + 输入校验)
处理边界情况,避免无限递归和非法输入:
const fib = (function() {
const cache = new Map([[0, 0], [1, 1]]);
return function(n) {
if (!Number.isInteger(n) || n < 0) {
throw new Error('n must be a non-negative integer');
}
if (cache.has(n)) return cache.get(n);
const result = fib(n - 1) + fib(n - 2);
cache.set(n, result);
return result;
};
})();
这个版本能安全应对 fib(50) 这类大数,不用重复算 fib(49)、fib(48) 等子问题。
不依赖递归的迭代缓存写法(推荐用于大数)
递归版在 n 很大时可能栈溢出;改用循环填充缓存,更稳定:
const fib = (function() {
const cache = new Map([[0, 0], [1, 1]]);
return function(n) {
if (!Number.isInteger(n) || n < 0) {
throw new Error('n must be a non-negative integer');
}
if (cache.has(n)) return cache.get(n);
<pre class="brush:php;toolbar:false;">let a = 0, b = 1;
for (let i = 2; i <= n; i++) {
const next = a + b;
cache.set(i, next);
a = b;
b = next;
}
return cache.get(n);}; })();
它按需从 2 开始逐个计算并缓存,既避免递归开销,又保持缓存可复用——下次调 fib(100) 时,前面的值都已在 cache 中。


















