函数可以将先操作的结果记录在某个对象里,从而避免无所谓的重复运算,这种优化被称为记忆化(Memoization)
常见的一个问题:斐波那契数列
常见的求解斐波那契数列的方法就是通过保存我们已经计算过的值,并将其隐藏在函数的闭包当中来避免重复计算,当函数被调用的时候,这个函数会首先检查结果是否存在,然后再做计算:
const fibonacci = (() => {
const memo = [0, 1]
const fib = (n) => {
let result = memo[n]
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2)
memo[n] = result
}
return result
}
return fib;
})();
console.log(fibonacci(10))
编写一个通用函数
const memoizer = (memo, formula) => {
const recur = (n) => {
let result = memo[n];
if (typeof result !== 'number') {
result = formula(recur, n);
memo[n] = result;
}
return result;
};
return recur;
}
现在,我们可以通过memoizer来定义fibonacci函数,并且提供基础的memo数组和formula函数
const fibonacci = memoizer([0, 1], (recur, n) => recur(n - 1) + recur(n - 2));
事实上在实践当中,我们对memo的管理,也可以使用公共对象or闭包等
使用效果:
const memo = [0, 1]
const fibonacci = memoizer(memo, (recur, n) => recur(n - 1) + recur(n - 2));
console.log(memo) // [ 0, 1 ]
console.log(fibonacci(10)) // 55
console.log(memo) // [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
console.log(fibonacci(5)) // 5
console.log(memo) // [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]