计算在JS中递归调用函数的次数

时间:2015-02-13 17:16:21

标签: javascript recursion

我有一个功课,我应该在JavaScript中编写一个伪随机数生成器。这是我写的代码位

var k = 0;

var slump = function(n, k) {
  if (k < 10) {
  console.log("stop");
  }
  else {
    k++;
    console.log((5*n + 1) % 8);
    return slump((5*n + 1) % 8, k);
  }
};

slump(0);

k应该保持调用函数的次数。但不是仅运行该函数十次,它只是继续运行。有没有办法解决这个问题?

3 个答案:

答案 0 :(得分:2)

这里有两个略有不同的选项,具体取决于你想要得到的惯用和聪明。

经典的实现,稍微调整,因为JS不支持默认参数,将使用类似的东西:

var finalDepth = 0;
function slump(n, k) {
    k = k || 0; // Set to 0 if falsy (null, undef, or 0)
    if (logic) {
        finalDepth = k; // Record the depth on the last call
    } else {
        return slump((5*n + 1) % 8, k + 1);
    }
}

这将非常简单地记录堆栈的最深处,并挂到该值直到下一次调用。

如果你想要更像JS,你可以使用闭包来跟踪调用:

function createGenerator() {
  var counter = 0;
  return {
    slump: function (n) {
      ++counter; // Closure captures counter, counter persists between slump calls but is unique for each createGenerator
      if (logic) {
        // stop
      } else {
        return slump((5*n + 1) % 8, k + 1);
      }
    },
    getCounter: function () { return counter; }
  }
}

您可以使用ES6 iterators(或生成器)中的某些功能来使其更加聪明。

答案 1 :(得分:0)

每当你编写一个递归函数时,你需要确保:

  1. 有一个基本案例(在您的情况下,当console.log语句运行时)
  2. 该功能继续进行基本情况,
  3. 假设递归调用成功,该函数有效。
  4. 你遇到了第二部分的问题;你增加k,但这并没有让你更接近k < 10的部分。简而言之,您可能希望切换该测试并确保最初使用正确数量的参数调用该函数。 (Aadit M Shah pointed out你用它来调用它,它预计有两个,这意味着当你调用它时它最终会被定义。)

    无论哪种方式,迭代肯定会在这里更好地工作:

    var n = 0;
    for(var i = 0; i < 10; i++) {
        n = (5 * n + 1) % 8;
        console.log(n);
    }
    

答案 2 :(得分:0)

函数参数k未初始化,因此不是数字。这尤其意味着终止测试k < 10失败,k++语句也不会改变k的值。因此,总是使用参数k的相同值调用slump,并且递归永远不会停止。