这个-11来自哪里?

时间:2012-03-25 20:47:01

标签: javascript

我正在玩下面的代码:

function recaller(){
    while(x-- > 0)recaller();
}

var x = 10;
recaller();
alert(x); //-11?

但我惊讶地发现x现在拥有-11的价值

我后来在alert(x);上方添加了while,以查看它是否正确显示了100的数字,并确实显示了。{/ p>

有人可以解释一下-11来自哪里吗?我的调试技巧这次失败了,我不知道如何继续测试

3 个答案:

答案 0 :(得分:17)

您正在递归recaller,因此x在递归结束时会多次递减 - 每次递归时,当您退出递归调用while循环时将再次检查条件,该表达式递减x。考虑如果我们从x = 2开始会发生什么:

  1. x为2,我们调用recaller(第一次)进入其while循环,检查x是否大于零,递减和...
  2. x为1,我们调用recaller(第二次)进入其while循环,检查x是否大于零,递减和...
  3. x为0,我们调用recaller(第三次)进入其while循环,检查x大于零,它不是,递减(-1)并返回
  4. 将堆栈展开一次到第二次;在while循环中,检查x大于零(否),递减(-2)并返回
  5. 第一次展开堆栈;在while循环中,检查x大于零(否),递减(-3)并返回
  6. 返回顶级流程
  7. x=-3

答案 1 :(得分:2)

执行此操作时:

var x = 10;
alert(x--); // Displays 10
alert(x); // Displays 9

x--是一个后递减运算符,即在主eval之后执行。因此:

if(x-- > 10) { 
  // Executes when x is > 10 before decrementing
}

您正在进行递归循环。即你这样做:

function recaller(){
    while(x-- > 0)recaller();
}

其中:

  • 比较x到10
  • 递归调用
  • 减少x

由于您的编码为x > 0,当x = 0时,它将从最内层调用退出recaller,然后减少一次,退出到下一个递归调用等,直到达到-11

答案 2 :(得分:2)

您可能知道,x--递减x然后在递减之前返回其值。我们也可以这样编写你的代码:

function recaller() {
    while(true) {
        var oldX = x;
        x--;
        if(!(oldX < 0)) {
            break;
        }
        recaller();
    }
}

现在将登录更容易。我认为通过一些缩进更容易看到,所以我有一些功能没有在这里显示。通过一些日志记录,它看起来像这样:

function recaller() {
    indent();
    log("Recaller called");
    while(true) {
        log("In loop, before decrement and test");
        var oldX = x;
        x--;
        log("In loop; decremented");
        if(!(oldX > 0)) {
            log("Test failed");
            break;
        }
        log("Test succeeded");
        log("In loop, before recursion");                    
        recaller();
        log("In loop, after recursion");
    }
    log("About to return from recaller");
    dedent();
}

你可以在JSFiddle上see the result

查看日志,即使测试失败,也可以判断它正在递减(低于零),导致负数。