在不使用全局变量的情况下在Javascript中缓存

时间:2017-02-16 16:22:16

标签: javascript

我正在尝试优化函数的用法,以检查数字是否为素数。

我写了以下函数:

function isPrime(num) {
    var start = 2;

    // code to check whether num has already been checked for Prime

    while(start <= Math.sqrt(num)) {
      if (num % start++ < 1) {
        return false;
      }
    }
    return num > 1;
}

但是,在执行while循环之前,我想检查一个数字是否已经通过我的isPrime函数传递,这样我就可以返回它是否是素数而不必执行{{ 1}}循环。

注意,我想在不使用全局变量或不扩展while的情况下执行此操作。

3 个答案:

答案 0 :(得分:3)

IIFE内声明变量以创建closure

var isPrime = (function () {
    var checked_numbers = [];

    function isPrime(num) { ... }

    return isPrime;
}();
对于返回的checked_numbers函数,

isPrime在范围中是(可以在IIFE外部访问,因为它(函数本身)被分配给全局变量),但是IIFE之外的任何东西都无法触及它。

答案 1 :(得分:3)

您可以使用Memoization技术。

Memoization是一种编程技术,它试图通过缓存以前计算的结果来提高函数的性能。

基本思想是我们构建一个空对象然后添加Keys作为哈希值或参数值,然后如果我们得到一个已经在Object键上可用的参数,那么我们返回该键的Object值。

以下功能有几种变体,但是这个功能比其他实现要好得多。从Addy Osmani文章here获取的代码片段。

function memoize( fn ) {
        return function () {
            var args = Array.prototype.slice.call(arguments),
                hash = "",
                i = args.length;
            currentArg = null;
            while (i--) {
                currentArg = args[i];
                hash += (currentArg === Object(currentArg)) ?
                JSON.stringify(currentArg) : currentArg;
                fn.memoize || (fn.memoize = {});
            }
            return (hash in fn.memoize) ? fn.memoize[hash] :
            fn.memoize[hash] = fn.apply(this, args);
        };
    }

<强>用法:

var cachedIsPrime = memoize(isPrime);
var isPrime = cachedIsPrime(2);
isPrime = cachedIsPrime(3);

然后你可以传递需要记忆的功能。

OP注意: 对于具有单个参数的上述上下文,如下所示的简单memoize函数可以工作:

var memoize = function(passedFunc) {
    var cache = {};
    return function(x) {
        if (x in cache) return cache[x];
        return cache[x] = passedFunc(x);
    };
};

答案 2 :(得分:1)

您要找的是 memoization 模式。

来自Wikipedia

  

在计算中, memoization 是一种优化技术   主要用于通过存储结果来加速计算机程序   昂贵的函数调用并返回缓存的结果时相同   输入再次发生。

您可以编写your own memoize function(根据其他答案的建议),也可以使用npm上提供的众多优化经过良好测试的实现之一,例如fast-memoize.jsmemoizee。如果您已经使用Lodash,它也有自己的_.memoize功能。

示例:

var isPrime = memoize(/* your function */)

isPrime(2) // => true
isPrime(2) // => true (from the cache)