【问题标题】:Javascript memoization without closure scope没有闭包范围的 Javascript 记忆
【发布时间】:2016-05-10 03:45:27
【问题描述】:

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. 他们的逻辑对我来说是有意义的,但是当我运行代码时,所发生的只是创建了 answers 属性,但没有添加任何内容 - 为什么?
  2. return isPrime.answers[value] = prime; 行对我来说很有趣,并且 repl.it 在我使用它时会发出警告。在同一行中分配和返回所有内容是否令人不快?

【问题讨论】:

  • 尝试用这个替换 isPrime
  • @ayushgp:为什么?那是错误的。你觉得this 会指什么?
  • 对我来说似乎工作得很好:jsfiddle.net/5u0ua5bpisPrime.answers 作为属性为 42 的对象。
  • 我和@FelixKling 在一起,它在本地对我有用。可能很愚蠢的问题,您是否在检查答案的值之前调用该函数?
  • @FelixKling 我认为它应该引用函数对象。没有,我查了。但那它指的是什么?

标签: javascript closures memoization


【解决方案1】:

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

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

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

表明answers 是一个非空对象:

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,副作用是不受欢迎的。也就是说,赋值是表达式并返回赋值是该语言的一个特性,只要它被负责任地使用,为什么不呢。

【讨论】:

    【解决方案2】:

    他们的逻辑对我来说很有意义

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

    在同一行中分配和返回所有内容是否令人不快?

    取决于你问谁,但它并没有被一致谴责为不好的做法。你说的好笑,别人觉得很迷惑,我个人觉得说的一清二楚。如果您不喜欢代码高尔夫并且想要安全起见,最好将其简单地拆分为两个语句:

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

    【讨论】:

    • 但是isPrime.answers 会在调用中持续存在,而var 不会。
    猜你喜欢
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多