我们可以通过使用闭包和对象来实现一个简单的函数缓存。
function memoize(fn) {
const cache = {}; // 存储函数输入和对应的输出
return function(...args) {
const key = JSON.stringify(args); // 使用输入参数作为缓存的键
if (cache[key]) {
console.log('Fetching from cache:', key);
return cache[key];
} else {
console.log('Calculating result:', key);
const result = fn(...args); // 计算结果
cache[key] = result; // 存储结果
return result;
}
};
}
// 示例函数:计算阶乘
function factorial(n) {
if (n === 0 || n === 1) return 1;
return n * factorial(n - 1);
}
const memoizedFactorial = memoize(factorial);
console.log(memoizedFactorial(5)); // Calculating result: [5]
console.log(memoizedFactorial(5)); // Fetching from cache: [5]
console.log(memoizedFactorial(6)); // Calculating result: [6]
console.log(memoizedFactorial(6)); // Fetching from cache: [6]
memoize
函数:
memoize
是一个高阶函数,接受一个函数 fn
作为参数,并返回一个新的函数。cache
对象,用于存储函数输入参数和对应的计算结果。闭包:
cache
对象在 memoize
函数内部定义,并且在返回的新函数中被引用,因此可以记住函数调用之间的状态。缓存机制:
key
)。函数缓存在很多场景中都非常有用,特别是那些具有高计算成本的场景:
计算密集型函数:
API调用:
数据转换和格式化:
前端性能优化:
async function fetchData(url) {
const response = await fetch(url);
const data = await response.json();
return data;
}
const memoizedFetchData = memoize(fetchData);
memoizedFetchData('https://api.example.com/data').then(data => {
console.log(data); // 第一次调用,会进行实际的API请求
});
memoizedFetchData('https://api.example.com/data').then(data => {
console.log(data); // 第二次调用,会返回缓存的结果
});
缓存大小和失效策略:
引用类型的比较:
JSON.stringify
将参数转换为字符串作为键,这对于简单的数据结构有效,但对于复杂的数据结构可能效率不高。可以考虑使用深比较或自定义序列化函数。函数副作用: