有人可以解释你在这个函数表达式中如何得到错误吗?

时间:2014-09-25 14:00:20

标签: javascript

我理解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

4 个答案:

答案 0 :(得分:7)

even(n)始终与even(n-1)相反。

由于even(0)trueeven(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,所以从!!否定自己,我们离开了!真实或虚假。

根据注释 - 因为这是一个递归函数,它期望在它达到零时结束,如果给它一个输入值是一个方式来检查,它将导致无限递归数字是否均匀。