我正在玩下面的代码:
function recaller(){
while(x-- > 0)recaller();
}
var x = 10;
recaller();
alert(x); //-11?
但我惊讶地发现x
现在拥有-11
的价值
我后来在alert(x);
上方添加了while
,以查看它是否正确显示了10
到0
的数字,并确实显示了。{/ p>
有人可以解释一下-11
来自哪里吗?我的调试技巧这次失败了,我不知道如何继续测试
答案 0 :(得分:17)
您正在递归recaller
,因此x
在递归结束时会多次递减 - 每次递归时,当您退出递归调用while
循环时将再次检查条件,该表达式递减x
。考虑如果我们从x = 2
开始会发生什么:
x
为2,我们调用recaller
(第一次)进入其while循环,检查x
是否大于零,递减和... x
为1,我们调用recaller
(第二次)进入其while循环,检查x
是否大于零,递减和... x
为0,我们调用recaller
(第三次)进入其while循环,检查x
大于零,它不是,递减(-1
)并返回x
大于零(否),递减(-2
)并返回x
大于零(否),递减(-3
)并返回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 > 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。
查看日志,即使测试失败,也可以判断它正在递减(低于零),导致负数。