未捕获的 RangeError:超出最大调用堆栈大小 - 为什么?/如何避免?
我使用的是常规 JavaScript。
正如标题所示,我遇到了 RangeError,但我真的不知道如何避免它。 真正的问题是我不应该遇到它,而且如果我刷新页面,有十分之一的机会(估计)不会抛出错误。
代码: (它是关于从数组中挑选随机对象)
我有一个这样的数组:
var array = ["item1", "item2", "item3", "item4"]
等等,实际上我有 5 个数组,总共包含大约 4000 个字符。 我使用一个函数来生成一个随机数:
function getRandomNumber(start, range) {
range = range + 1;
return Math.floor( (Math.random() * (range - start) ) + start );
}
这个函数有效,我甚至在网络的帮助下改进了我最初的方法,使它看起来像现在这样。
所以我这样调用这个函数:
function getObjects() {
var randomObject1 = array[getRandomNumber(1, array.length -1)]
var randomObject2 = array[getRandomNumber(1, array.length -1)]
var randomObject3 = array[getRandomNumber(1, array.length -1)]
var drawnItems = [randomObject1, randomObject2, randomObject3]
if(drawnItems.length != new Set(drawnItems).size) {
getObjects()
}
}
我需要每轮绘制多个对象,所以我像所示那样多次执行此操作。 我最终得到一个包含如上所示随机绘制项目的数组。
然后我使用此代码来确定绘制的项目是否可以存储在 Set 中,这并不重要,但却是一种检查是否有任何对象被绘制两次的便捷方法。 => 在最终输出中,我只能让每个对象出现一次。
我可以看到这一切都是如何有问题的,但我不明白为什么计算机会面临这个问题,而如果我刷新几次,我就不会。我想说的是,事实上,计算机尝试的次数比我必须刷新才能达到有效星座的次数要多。 为什么 PC 会遇到这个问题,即使它尝试的次数更多?
当我尝试从仅包含 4 个对象的数组中绘制 3 个对象时,第一次发生了这种情况。如果我从 100 多个对象的大数组中绘制,我永远不会遇到问题。
这是一个递归问题。您的函数会一遍又一遍地调用自身,直到堆栈填满并导致显示的错误。
如果删除这些代码行,您将解决错误:
if(drawnItems.length != new Set(drawnItems).size) {
getObjects()
}
您有理由使用 if 条件来执行递归吗?
编辑:
为了避免重复的值,您可以使用以下代码来删除递归:
//First object won't be duplicated, so we declare it directly
var randomObject1 = array[getRandomNumber(1, array.length -1)];
var randomObject2 = null, randomObject3 = null;
do {
randomObject2 = array[getRandomNumber(1, array.length -1)];
} while (randomObject2 == randomObject1);
do {
randomObject3 = array[getRandomNumber(1, array.length -1)];
} while (randomObject3 == randomObject1 || randomObject3 == randomObject2);
使用上述代码,您将不断为 randomObject2 和 randomObject3 生成随机值,而它们与另一个值相同。
getObjects 函数中有一个无限循环
此部分:
//...
if(drawnItems.length != new Set(drawnItems).size) {
getObjects()
}
//...
此函数无限次调用自身,直到达到限制。这就是您收到此错误的原因。尝试使用循环,也许会有所帮助。
此外,我还发现了一些对您有帮助的东西: 超出最大调用堆栈大小错误