Where did this come from?

I played with the following code:

function recaller(){ while(x-- > 0)recaller(); } var x = 10; recaller(); alert(x); //-11? 

But I was amazed to find that x now has a value of -11

I later added alert(x); above while , to make sure that it correctly displays the numbers 10 to 0 , and this happened.

Can someone explain to me where -11 came from? My debugging skills did not help me this time, and I don’t know how to continue testing

+4
source share
3 answers

You return to recaller , so x gets many times at the end of the recursion - every time you recurs, when you exit this recursive call, the condition of the while will be checked again, and this expression reduces x . Consider what happens if we start with x = 2 :

  • x is equal to 2, we call recaller (the first time), we introduce its while loop, which checks x greater than zero, decreases and ...
  • x is equal to 1, we call recaller (the second time), we introduce its while loop, which checks x greater than zero, decreases and ...
  • x is 0, we call recaller (the third time), we introduce its while loop, which checks x greater than zero, which is not there, decreases ( -1 ) and returns
  • expand the stack once a second time; in its while loop, checking x greater than zero (no), decreasing ( -2 ) and returning
  • unlock the stack once for the first time; in its while loop, checking x greater than zero (no), decrees ( -3 ) and returns
  • return to top level thread
  • x=-3
+17
source

When you do this:

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

x-- is a post-decrement operator, i.e. executed after the main eval. Thus:

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

You are doing a recursive loop. That is, you do:

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

What:

  • Compares x to 10
  • Invokes recursively
  • Lower x

Since your encoding is x > 0 , it will go from the innermost call to recaller when x = 0, then decrement once, exit to the next recursive call, etc., until you reach -11.

+2
source

As you probably know, x-- decreases x , and then returns its value to decrement. We can also write your code as follows:

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

Now it’s easier to log in. I think this is a little easier to see with some indentation, so I have a few functions that are not shown here. With some logging, it looks like this:

 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(); } 

You can see the result on JSFiddle.

Looking at the magazine, you can say that it reduces it (to zero below zero) even if the test fails, which leads to a negative number.

+2
source

Source: https://habr.com/ru/post/1403351/


All Articles