我理解if
的第一部分,但不是第二部分陈述"因为' n'不等于零,返回' n'在使用逻辑NOT(!)运算符修改的even函数中。"?
如果我将5作为参数传递给fn();
,那么它不会返回4吗?
var fn = function even (n)
{
if (n === 0)
{
return true;
}
else
{
return !even(n - 1)
}
};
fn(5); //=> false
答案 0 :(得分:7)
even(n)
始终与even(n-1)
相反。
由于even(0)
为true
,even(1)
为false
,依此类推:所有2的倍数均为true
,奇数则为false
查看它的简单方法可能是记录[0,1,2,3,4,5].map(even)
。
万一你真的在寻找一种方法来了解正整数是否均匀,你所展示的解决方案效率非常低,并且递归会导致任何大数字的调用堆栈爆炸。这是一个更合理的解决方案:
function even(n){
return !(n%2);
}
答案 1 :(得分:5)
不是使用布尔值NOT修改even
函数,而是将NOT应用于使用even
调用n - 1
函数的结果。不返回4,但!(even(4))
。
如果我们将功能简化为
function even(n) { return n==0 || !even(n-1); }
我们会对您的通话进行以下扩展:
even(5)
5==0 || !even(5-1)
!even(4)
!(4==0 || !even(4-1))
!!even(3)
!!(3==0 || !even(3-1))
!!!even(2)
!!!(2==0 || !even(2-1))
!!!!even(1)
!!!!(1==0 || !even(1-1))
!!!!!even(0)
!!!!!(0==0 || !even(0-1))
!!!!!(true || !even(0-1))
!!!!!true
!!!!false
!!!true
!!false
!true
false
答案 2 :(得分:2)
我认为通过展示返回时!
没有var fn = function even (n){
if (n === 0) return true;
else return even(n - 1)
}
会发生什么情况,可以最好地解释。如果我们有:
true
它总是会返回0
,因为它最终会点击fn(3)
。如果我们调用fn(3)
-> fn(2)
-> fn(1)
-> fn(0)
true
true
true
true
true
,调用堆栈将如下所示:
!
递归调用中的fn(3)
-> fn(2)
-> fn(1)
-> fn(0)
true
!true
!(!true)
!(!(!true))
!(!(!(!true)))
否定了之前的值,因此新的调用堆栈如下所示:
!(!(!(!true))) === true
{{1}}
答案 3 :(得分:0)
这是递归计算是否为正整数(参见结尾处的注释)是偶数的低效但有效的方法。基本上,每次检查一个非零数字时,你都依赖于n是否为偶数与n-1是否为偶数相同的事实。因此,偶数(5)与!偶数(4)相同,并且!偶数(4)与!!偶数(3)(或偶数(3))相同。所以到最后,你计算偶数(5)为!!!!!偶数(0)。我们知道even(0)返回true,所以从!!否定自己,我们离开了!真实或虚假。
根据注释 - 因为这是一个递归函数,它期望在它达到零时结束,如果给它一个输入值是一个好方式来检查,它将导致无限递归数字是否均匀。