没有封闭范围的Javascript memoization

时间:2016-05-10 03:45:28

标签: javascript closures memoization

JavaScript Ninja的秘密中,作者提出了以下方案,用于在没有闭包的情况下记忆函数结果。他们通过利用函数是对象并在函数上定义属性来实现这一点,该函数存储过去调用函数的结果。

function isPrime(value) {
    if (!isPrime.answers) isPrime.answers = {};
    if (isPrime.answers[value] != null) {
        return isPrime.answers[value];
    }
    var prime = value != 1
    for (var i = 2; i < value; i++) {
        if (value % i === 0) {
            prime = false;
            break;
        }
    }
    return isPrime.answers[value] = prime;
}

我有两个问题

  1. 他们的逻辑对我来说很有意义,但是当我运行代码时,所有发生的事情都是创建了答案属性但没有添加任何内容 - 为什么?
  2. return isPrime.answers[value] = prime;对我来说很有趣,当我使用它时,repl.it会发出警告。分配并返回同一行中的所有人不赞成?

2 个答案:

答案 0 :(得分:2)

  

1。他们的逻辑对我来说很有意义,但是当我运行代码时,所有发生的事情都是创建了答案属性但没有添加任何东西 - 为什么?

对我来说似乎工作得很好。

console.log(isPrime(42));
console.log(isPrime.answers)

表明answers是非空对象:

enter image description here

function isPrime(value) {
    if (!isPrime.answers) isPrime.answers = {};
    if (isPrime.answers[value] != null) {
        return isPrime.answers[value];
    }
    var prime = value != 1
    for (var i = 2; i < value; i++) {
        if (value % i === 0) {
            prime = false;
            break;
        }
    }
    return isPrime.answers[value] = prime;
}

console.log(isPrime(42));
console.log(isPrime.answers)

  

2。 [...]分配并返回同一行中的所有人不赞成?

在这种情况下,作业基本上是side effect,副作用令人不悦。也就是说,作为表达式并返回指定值的赋值是语言的一个特征,只要它被负责任地使用,为什么不呢。

答案 1 :(得分:1)

  

他们的逻辑对我有意义

不应该。该方案仍然依赖于闭包,特别是函数所在范围内的isPrime变量。它们同样可以使用var isPrimeAnswers = {};而不是isPrime.answers = {};(两者都应该放在在功能体外。)

  

分配并返回同一行中的所有内容并不赞成?

取决于你问谁,但并不是一致谴责这是一种不良做法。你说它很有趣,其他人觉得这很混乱,我个人认为它很清楚。如果您没有进入高尔夫代码并希望保持安全,那么最好将其分成两个语句:

isPrime.answers[value] = prime;
return prime;