Javascript 变量有时不';t生成:最大调用堆栈大小问题

Javascript 变量有时不';t生成:最大调用堆栈大小问题,javascript,recursion,Javascript,Recursion,错误在文章底部详细说明,但在开始之前,我会给出一些背景信息。我有以下脚本,它生成: 1)2和20之间的两个不同数字 var GenerateRandomNumber1to20No1 = GenerateRandomNumber1to20No1(); $('.GenerateRandomNumber1to20No1').html(GenerateRandomNumber1to20No1); function GenerateRandomNumber1to20No2() { var

错误在文章底部详细说明,但在开始之前,我会给出一些背景信息。我有以下脚本,它生成:

1)2和20之间的两个不同数字

 var GenerateRandomNumber1to20No1 = GenerateRandomNumber1to20No1(); 
$('.GenerateRandomNumber1to20No1').html(GenerateRandomNumber1to20No1);

 function GenerateRandomNumber1to20No2() {
    var min = 2, max = 20;
    var random = Math.floor(Math.random() * (max - min + 1)) + min;   
  return (random !== GenerateRandomNumber1to20No1) ? random: GenerateRandomNumber1to20No2();

}

 var GenerateRandomNumber1to20No2 = GenerateRandomNumber1to20No2(); 
$('.GenerateRandomNumber1to20No2').html(GenerateRandomNumber1to20No2);

 function GenerateRandomNumber1to20No3() {
    var min = 2, max = 20;
    var random = Math.floor(Math.random() * (max - min + 1)) + min;   
   return (random !== GenerateRandomNumber1to20No1 && random!==GenerateRandomNumber1to20No2) ? random: GenerateRandomNumber1to20No3();

}
2)比前两个数字少两个不同的数字

function GenerateRandomNumber1to20lessthanNo1() {
    var min = 2, max = GenerateRandomNumber1to20No1-1;
    var random = Math.floor(Math.random() * (max - min + 1)) + 1;   
    return random;

}

 var GenerateRandomNumber1to20lessthanNo1= GenerateRandomNumber1to20lessthanNo1(); 
$('.GenerateRandomNumber1to20lessthanNo1').html(GenerateRandomNumber1to20lessthanNo1);

function GenerateRandomNumber1to20lessthanNo2() {
    var min = 2, max = (GenerateRandomNumber1to20No2 - 1);
    var random = Math.floor(Math.random() * (max - min + 1)) + min;   
  return (random !== GenerateRandomNumber1to20lessthanNo1) ? random: GenerateRandomNumber1to20lessthanNo2();

}

 var GenerateRandomNumber1to20lessthanNo2 = GenerateRandomNumber1to20lessthanNo2(); 
$('.GenerateRandomNumber1to20lessthanNo2').html(GenerateRandomNumber1to20lessthanNo2);
    function PrimeNumber1() {
  var PrimeNumber1= ['3', '5', '7', '11'];
    var PrimeNumber1random= PrimeNumber1[Math.floor(Math.random() * PrimeNumber1.length)];
    return PrimeNumber1random;

}

var PrimeNumber1replacer= PrimeNumber1();
 $('.PrimeNumber1replacer').html(PrimeNumber1replacer);

    function PrimeNumber2() {
  var PrimeNumber2= ['3', '5', '7', '11'];
    var PrimeNumber2random= PrimeNumber2[Math.floor(Math.random() * PrimeNumber2.length)];
    return (PrimeNumber2random !== PrimeNumber1replacer) ? PrimeNumber2random: PrimeNumber2();

}

var PrimeNumber2replacer= PrimeNumber2();
 $('.PrimeNumber2replacer').html(PrimeNumber2replacer);
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20lessthanNo1"></span>
<span class = "GenerateRandomNumber1to20lessthanNo2"></span>
<span class = "PrimeNumber1replacer"></span>
<span class = "PrimeNumber2replacer"></span>
3)两个不同的素数

function GenerateRandomNumber1to20lessthanNo1() {
    var min = 2, max = GenerateRandomNumber1to20No1-1;
    var random = Math.floor(Math.random() * (max - min + 1)) + 1;   
    return random;

}

 var GenerateRandomNumber1to20lessthanNo1= GenerateRandomNumber1to20lessthanNo1(); 
$('.GenerateRandomNumber1to20lessthanNo1').html(GenerateRandomNumber1to20lessthanNo1);

function GenerateRandomNumber1to20lessthanNo2() {
    var min = 2, max = (GenerateRandomNumber1to20No2 - 1);
    var random = Math.floor(Math.random() * (max - min + 1)) + min;   
  return (random !== GenerateRandomNumber1to20lessthanNo1) ? random: GenerateRandomNumber1to20lessthanNo2();

}

 var GenerateRandomNumber1to20lessthanNo2 = GenerateRandomNumber1to20lessthanNo2(); 
$('.GenerateRandomNumber1to20lessthanNo2').html(GenerateRandomNumber1to20lessthanNo2);
    function PrimeNumber1() {
  var PrimeNumber1= ['3', '5', '7', '11'];
    var PrimeNumber1random= PrimeNumber1[Math.floor(Math.random() * PrimeNumber1.length)];
    return PrimeNumber1random;

}

var PrimeNumber1replacer= PrimeNumber1();
 $('.PrimeNumber1replacer').html(PrimeNumber1replacer);

    function PrimeNumber2() {
  var PrimeNumber2= ['3', '5', '7', '11'];
    var PrimeNumber2random= PrimeNumber2[Math.floor(Math.random() * PrimeNumber2.length)];
    return (PrimeNumber2random !== PrimeNumber1replacer) ? PrimeNumber2random: PrimeNumber2();

}

var PrimeNumber2replacer= PrimeNumber2();
 $('.PrimeNumber2replacer').html(PrimeNumber2replacer);
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20lessthanNo1"></span>
<span class = "GenerateRandomNumber1to20lessthanNo2"></span>
<span class = "PrimeNumber1replacer"></span>
<span class = "PrimeNumber2replacer"></span>
我使用这些变量将元素替换为具有相应变量值的相应类

function GenerateRandomNumber1to20lessthanNo1() {
    var min = 2, max = GenerateRandomNumber1to20No1-1;
    var random = Math.floor(Math.random() * (max - min + 1)) + 1;   
    return random;

}

 var GenerateRandomNumber1to20lessthanNo1= GenerateRandomNumber1to20lessthanNo1(); 
$('.GenerateRandomNumber1to20lessthanNo1').html(GenerateRandomNumber1to20lessthanNo1);

function GenerateRandomNumber1to20lessthanNo2() {
    var min = 2, max = (GenerateRandomNumber1to20No2 - 1);
    var random = Math.floor(Math.random() * (max - min + 1)) + min;   
  return (random !== GenerateRandomNumber1to20lessthanNo1) ? random: GenerateRandomNumber1to20lessthanNo2();

}

 var GenerateRandomNumber1to20lessthanNo2 = GenerateRandomNumber1to20lessthanNo2(); 
$('.GenerateRandomNumber1to20lessthanNo2').html(GenerateRandomNumber1to20lessthanNo2);
    function PrimeNumber1() {
  var PrimeNumber1= ['3', '5', '7', '11'];
    var PrimeNumber1random= PrimeNumber1[Math.floor(Math.random() * PrimeNumber1.length)];
    return PrimeNumber1random;

}

var PrimeNumber1replacer= PrimeNumber1();
 $('.PrimeNumber1replacer').html(PrimeNumber1replacer);

    function PrimeNumber2() {
  var PrimeNumber2= ['3', '5', '7', '11'];
    var PrimeNumber2random= PrimeNumber2[Math.floor(Math.random() * PrimeNumber2.length)];
    return (PrimeNumber2random !== PrimeNumber1replacer) ? PrimeNumber2random: PrimeNumber2();

}

var PrimeNumber2replacer= PrimeNumber2();
 $('.PrimeNumber2replacer').html(PrimeNumber2replacer);
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20nNo2"></span>
<span class = "GenerateRandomNumber1to20lessthanNo1"></span>
<span class = "GenerateRandomNumber1to20lessthanNo2"></span>
<span class = "PrimeNumber1replacer"></span>
<span class = "PrimeNumber2replacer"></span>

我试图对Stackoverflow做一些研究,似乎这可能是递归的问题,但我不知道如何解决这个问题。如果有人有任何建议,我将不胜感激


谢谢大家!

由于几乎没有一个JS引擎兼容ES6,因此会出现堆栈溢出,因此即使使用尾部递归,也会破坏堆栈。现在最好的办法是将它重写成一个循环,直到成功为止

function generateRandomNumber(predicate = v => true) {
    const min = 2;
    const max = 20;
    let random;
    do {
        random = Math.floor(Math.random() * (max - min + 1)) + 1;
    } while (!predicate(random));
    return random;
}

// two different numbers
const first1 = generateRandomNumber();
const second1 = generateRandomNumber(v => v !== first1);

// two different number less than previous
const first2 = generateRandomNumber();
const second2 = generateRandomNumber(v => v < first2); // possible infinite loop

// two different prime numbers
function isPrime(n) {
  if (n % 2 === 0) return n == 2
  const limit = Math.sqrt(n);
  for (let i = 3; i <= limit; i += 2) {
    if (n % i === 0)
      return false;
  }
  return true;
}

const first3 = generateRandomNumber(isPrime);
const second3 = generateRandomNumber(v => isPrime(v) && v !== first3);
function generateRandomNumber(谓词=v=>true){
常数min=2;
常数max=20;
让随机;
做{
随机=数学地板(数学随机()*(最大-最小+1))+1;
}而(!谓词(随机));
返回随机;
}
//两个不同的数字
const first1=generateRandomNumber();
const second1=generateRandomNumber(v=>v!==first1);
//比以前少了两个不同的数字
const first2=generateRandomNumber();
const second2=generateRandomNumber(v=>v
我省略了将值放入DOM的代码,因为它不是很有趣。我没有在函数后命名变量,因为它们共享相同的名称空间,因此在将名称
generaterandomnumber1设置为20no1
后,函数已被值替换


请注意,我提到了“两个不同的数字比前一个少”你可能会得到一个无限循环。有5.5%的几率第一个随机数是
2
。同一个函数生成的数字没有小于
2
的,因此它不会终止。

使用循环而不是递归。我是一个完全的新手,不幸的是,我不知道这意味着什么。我可以肯定请仔细查找,但我的代码中是否有任何特定的部分需要我针对/切换?@Barmar您可以为OP添加一个解释,说明为什么在这种情况下循环递归吗?一个更大的问题可能是您对变量和函数使用了相同的名称。这不起作用,一个名称一次只能命名一件事。有关如何命名的信息,请参阅o生成N个唯一的随机数。类似的解决方案可用于其他问题。非常感谢您这么做。为了确保我正确理解这一点,如果我添加
var first2=generateRandomNumber();$('.first2').html(first2);
会用变量
first2
替换类为
first2
的元素吗?@Snoops不是真的。它会将结果添加为具有该类的标记体。因此,如果有
,它将变为
5
,而不仅仅是
5
。请注意,函数名使用的变量和用作类的字符串需要具有相同的名称,您当然也不需要使用我选择的变量名称。这是否需要node.js链接?我尝试时代码不起作用;我以前从未见过
const
,当我查找它时,它看起来好像是针对node.js框架的。@Snoops这是标准的ES6.和
let
是块作用域
var
并且支持很长时间,因此您需要使用非常旧的浏览器才能使其不工作。IE中不支持箭头函数,所以我认为可能是这样。
v=>v!==first1
=>
函数(v){return v!==first1;}
const
/
let
==>
var
将适用于此答案中的代码。