JavaScript Memoization:构造带有记忆功能的函数

98 阅读1分钟

函数可以将先操作的结果记录在某个对象里,从而避免无所谓的重复运算,这种优化被称为记忆化(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]

httpweixin.qq.comr5RGXj2jETTUyrSzs90T3.png

来源:前端妙妙屋 - 前端开发者的学习资源