所以,我正在浏览“JavaScript Allonge”并且有这个函数来模拟数组的.length
函数:
const length = ([first, ...rest]) =>
first === undefined
? 0
: 1 + length(rest);
现在,如果我将函数重写为:
var lengthy = (first, ...rest) =>
first === undefined ? 0 : 1 + lengthy(rest)
它给出了Maximum call stack size exceeded
,为什么?我打电话给我的版本是这样的:
lengthy(1)
答案 0 :(得分:3)
您需要在递归调用中使用扩展语法,否则您将传递数组作为第一个参数,然后 rest 参数将是一个空数组。这将无休止地继续下去。
所以:
var lengthy = (first, ...rest) =>
first === undefined ? 0 : 1 + lengthy(...rest);
console.log(lengthy(1,2,3,8,11));

请注意,在初始调用 rest 是一个数组,其中包含所有剩余的参数。在上面的示例中, rest 将为[2,3,8,11]
。这就是其余语法为您所做的。
现在你可以看到你的递归调用看起来如何再次传播该数组:
lengthy(rest)
...变为
lengthy([2,3,8,11])
所以现在递归调用中的参数是:
first = [2,3,8,11]
rest = []
如果您继续进行此分析,您会看到下一个电话是:
first = []
rest = []
这将永远持续下去。
现在通过更正lengthy(...rest)
,实际调用将在示例中:
lengthy(2,3,8,11)
......这就是你想要的。现在,first
和rest
的下一个值将是:
first = 2
rest = [3,8,11]
...等
答案 1 :(得分:2)
答案与destructuring有关。
在原文中,你有:
otool
在第二个答案中,您有:
([first, ...rest])
原始数组将一个数组作为参数,并对数组进行解构,以便第一个元素位于(first, ...rest)
中,其余元素位于first
中。
第二个不会对数组进行解构,并将您传入的数组放入第一个,使rest
成为空数组。这是递归调用的。在对rest
的所有递归调用中,lengthy
永远不会为空。
答案 2 :(得分:1)
var lengthy = ([first, ...rest]) => first === undefined ? 0 : 1 + lengthy(rest)
// lengthy gets passed ONE argument, an array
这很可能是因为第一个从不评估为0会导致无限循环。
length
接受一个参数,即一个数组。
lengthy
接受任意数量的参数,并对它们进行计数,但是当你以递归方式调用它时,你只传递它一个。
因此,当第二次调用lengthy
时,...rest
为undefined
,并在递归调用中传递给lengthy,这意味着first
将从此开始undefined
并导致您的错误。