[英]Javascript factorial function stack overflow
Why does the following javascript factorial function throw a stack overflow error when called?为什么以下 javascript 阶乘函数在调用时会抛出堆栈溢出错误?
function fact(n) {
return function () {
var n = n;
return (n < 2) ? 1 : (n*fact(n - 1));
}();
};
When I remove the line var n = n;
当我删除行
var n = n;
it works as expected.它按预期工作。 Also, I'm aware that the inner function is redundant, it's just there to trigger the error.
另外,我知道内部函数是多余的,它只是用来触发错误。
var n = n
in that situation effectively does n = undefined
because the formal parameter n
and the declared n
are from different scopes. var n = n
在这种情况下有效地执行n = undefined
因为形式参数n
和声明的n
来自不同的范围。 In your comment declaration n
and formal parameter n
are in same scope so it's not the same situation.在您的注释声明中,
n
和形式参数n
在同一范围内,因此情况不同。
undefined < 2
is always false, so it keeps calling fact
forever. undefined < 2
总是假的,所以它永远调用fact
。
var n = n
<- two problems here. var n = n
<- 这里有两个问题。
1: You have two variable with the same name, how could they be differenciated 1:你有两个同名的变量,怎么区分
2: var n = n
is equal to var n = undefined
, witch result in false
return
and loop forever 2:
var n = n
等于var n = undefined
,导致false
return
并永远循环
What you want to do is :你想要做的是:
function fact(n1) {
return function (n1) {
var n = n1;
return (n < 2) ? 1 : (n*fact(n - 1));
}();
};
The line var n = n;
线
var n = n;
isn't necessary, because it's defining a ' new ' variable called n
, and setting it to n
.没有必要,因为它定义了一个名为
n
的“新”变量,并将其设置为n
。
Your function is returning the result from an anonymous function, which isn't necessary.您的函数正在从匿名函数返回结果,这是不必要的。
The parameter n
is in the main function, not the anonymous function.参数
n
在主函数中,而不是匿名函数中。
I also spaced the *
symbol, in (n*fact(n - 1))
我也将
*
符号隔开,在(n*fact(n - 1))
The original code:原始代码:
function fact(n) { return function () { var n = n; return (n < 2) ? 1 : (n*fact(n - 1)); }(); };
The updated code:更新后的代码:
function fact(n) { return (n < 2) ? 1 : (n * fact(n - 1)); };
@ Esailija already explained the cause. @Esailija已经解释了原因。 Try:
尝试:
function fact(n) {
return function(n) {return n && n > 1 && n*(fact(n-1)) || 1;}(n);
// ^ pass n here
};
Or use the closure:或者使用闭包:
function fact(n) {
return function() {return n && n > 1 && n*(fact(n-1)) || 1;}();
};
Or indeed just use:或者确实只是使用:
function fact(n) {
return n && n > 1 && n*(fact(n-1)) || 1;
};
You only need to omit the re-declaration of var n
and the code is working fine.您只需要省略
var n
的重新声明,代码就可以正常工作。 But i would go for a for
loop in this one, it makes half the time.但是我会在这个循环中使用
for
循环,它会占用一半的时间。
function fact(n) { return function () { return (n < 2) ? 1 : (n*fact(n - 1)); }(); }; let startDate = performance.now(); console.log(fact(170),`fact(170) took: ${(performance.now()-startDate)} milliseconds`); function fact2(n) { let result = 1; for(let i = 2; i <=n; i++) { result *= i; } return result; } startDate = performance.now(); console.log(fact2(170),`fact2(170) took: ${(performance.now()-startDate)} milliseconds`);
PS: the timing was made out of curiosity. PS:时间是出于好奇。 I wanted to see a difference between the timed needed in this answer on a somehow relative answer that involved
Julia
programming language.我想在涉及
Julia
编程语言的某种相对答案上看到此答案中所需的时间之间的差异。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.