memoize

    如果一个函数调用开销很大,我们就可能希望能把结果缓存下来,以便后续调用时直接获得结果。举个例子,计算阶乘就比较耗时:

    'use strict';



    function factorial(n) {

    console.log('start calculate ' + n + '!…');

    var s = 1, i = n;

    while (i > 1) {

    s = s * i;

    i —;

    }

    console.log(n + '! = ' + s);

    return s;

    }



    factorial(10); // 3628800

    // 注意控制台输出:

    // start calculate 10!…

    // 10! = 3628800

    memoize() 就可以自动缓存函数计算的结果:

    'use strict';



    var factorial = _.memoize(function(n) {

    console.log('start calculate ' + n + '!…');

    var s = 1, i = n;

    while (i > 1) {

    s = s * i;

    i —;

    }

    console.log(n + '! = ' + s);

    return s;

    });



    // 第一次调用:

    factorial(10); // 3628800

    // 注意控制台输出:

    // start calculate 10!…

    // 10! = 3628800



    // 第二次调用:

    factorial(10); // 3628800

    // 控制台没有输出

    对于相同的调用,比如连续两次调用 factorial(10) ,第二次调用并没有计算,而是直接返回上次计算后缓存的结果。不过,当你计算 factorial(9) 的时候,仍然会重新计算。

    可以对 factorial() 进行改进,让其递归调用:

    'use strict';



    var factorial = _.memoize(function(n) {

    console.log('start calculate ' + n + '!…');

    if (n < 2) {

    return 1;

    }

    return n * factorial(n - 1);

    });



    factorial(10); // 3628800

    // 输出结果说明factorial(1)~factorial(10)都已经缓存了:

    // start calculate 10!…

    // start calculate 9!…

    // start calculate 8!…

    // start calculate 7!…

    // start calculate 6!…

    // start calculate 5!…

    // start calculate 4!…

    // start calculate 3!…

    // start calculate 2!…

    // start calculate 1!…



    factorial(9); // 362880

    // console无输出