函数缓存是什么
在JavaScript中,函数缓存(Function Caching)是一种优化技术,旨在避免重复执行代价高昂的计算。通过缓存函数的输出结果,并在需要时直接返回缓存的值,我们可以显著提高程序的效率,特别是当处理复杂计算或重复请求相同数据的情况时。
函数缓存可以通过多种方式实现,但基本概念相同:当函数第一次被调用时,其结果被存储在某个地方(如对象、Map等),当相同的参数再次传入时,函数不执行其原始逻辑,而是直接从缓存中返回结果。
本质:用空间(缓存存储)换事件(计算过程)
function memoize(fn) {
const cache = new Map();
return function(...args) {
const key = args.join(',');
if (cache.has(key)) {
return cache.get(key);
}
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}
const count = (x, y) => x + y;
const fm = memoize(count);
console.log(fm(10, 20)); // 调用函数并缓存结果 "10,20": 30
console.log(fm(10, 20)); // 直接从缓存中获取结果 "10,20": 30
console.log(fm(10, 30)); // 调用函数并缓存结果 "10,30": 40
console.log(fm(10, 30)); // 直接从缓存中获取结果 "10,30": 40
如何实现
函数缓存主要依靠闭包、柯里化以及高阶函数
闭包(Closure)
闭包允许一个函数访问并操作函数之外的变量。在函数缓存的上下文中,闭包可以用来封装缓存对象(如Map或对象字面量),以便在多次函数调用之间保持状态。
(function(){
var a = 1
function count(){
const b = 2
let sum = a + b
console.log(sum);
}
count()
})
柯里化(Currying)
柯里化是一种将使用多个参数的函数转换成一系列使用一个参数的函数的技术。在函数缓存中,柯里化可以用来逐步构建缓存键,特别是当函数有多个参数时。然而,在简单的缓存实现中,柯里化可能不是必需的,但它可以用于更复杂的场景,比如部分应用(partial application)和参数复用。
// 非柯里化
var count = function(a,b){
return a + b
}
count(1,2) //3
// 柯里化函数
var count2 = function(a){
return function(b){
return a + b
}
}
count2(2)(3)//5
高阶函数(Higher-Order Function)
高阶函数是至少满足下列一个条件的函数:
- 接受一个或多个函数作为输入。
- 输出一个函数。
在函数缓存的实现中,高阶函数通常用于接收一个待缓存的函数,并返回一个新的、经过缓存处理的函数。
function createFunction(f, x) {
return function() {
return f(x);
};
}
// 示例函数
function square(n) {
return n * n;
}
// 使用高阶函数
const squareOfTen = createFunction(square, 10);
// 调用返回的函数
console.log(squareOfTen()); // 输出: 100