Salman Oskooi
Salman Oskooi

Reputation: 366

Why does this condition in a while loop get executed as though it were part of the loop body?

Here's the relevant function (this example is taken from here):

​function factorial (num) {
  if (num < 0) {
    return -1;
  }
  else if (num == 0) {
    return 1;
  }
var tmp = num; 
  while (num-- > 2) {
    tmp = tmp * num;
  }
return tmp;
}
console.log(factorial(8));
----> 40320

As I was studying how this function works (and got stumped on the operator precedence in the expression (num-- > 2); kudos to my mentor Edwin Calte at MakerSquare for pointing that out), I noticed that the num variable decrements even though this decrementation is something that is stipulated as a precondition for the loop body to be executed and is not itself part of the loop body. I could understand why it would do that if the expression read instead like:

while (num-- > 2) {
num--;
...}

In the above example, that second num-- isn't necessary for it to work. Another similar expression where this doesn't seem to happen when I run it in my devtools console is:

if (x - 2 == 5) { x-- }

Here, it seems that if x is 7 then x will decrement by 1, ​not​ that if x is 7 then 2 will be subtracted from x, and then x will decrement by 1. But in the above example with ​num​, the latter principle is what takes effect.

Could someone please explain why?

Upvotes: 0

Views: 118

Answers (3)

ChevCast
ChevCast

Reputation: 59213

Because every time the expression num-- is evaluated (which it is on every iteration of the loop to see if the condition is met) it is decreasing num by one. A lot of JavaScript gurus will tell you to avoid num--, num++, --num, ++num exactly because of their not-so-intuitive side effects.

My advice would be to stick with things that are more readable at first glance, even if it is a few more characters to type.

while (num > 2) {
  num = num - 1;
}

At the very least, only use them as standalone statements to make what they are doing clear.

while (num > 2) {
  num--;
}

In your second example with the expression x - 2 == 5, this expression does not operate on x at all; it doesn't change it's value. You're not assigning anything back to x like you are when you do x--. x--; is exactly equivalent to x = x - 1;. It just so happens that it also returns the value of x before the assignment is made; this way it can be used as the conditional. It's like reading from a variable and then writing to it all in one statement.

Upvotes: 1

Barmar
Barmar

Reputation: 780974

num-- does two things: it subtracts 1 from the variable num (assigning the result back to num) and also returns the original value of the num to be used in the rest of the enumpression. So

(num-- > 2)

is short for:

(temp = num; num = num - 1; temp > 2)

Your while loop could be written as:

while (num > 2) {
    num--;
    tmp = tmp * num;
}

Notice that I no longer have num-- in the while clause. If I did, the variable would get decremented twice: once while testing the condition, and again inside the loop.

Upvotes: 1

Paul
Paul

Reputation: 646

x - 2 would express a new value, ie if you opened the console and typed x - 2 it would respond with 5, but that value is not assigned to anything (and thus x is unaffected). The -- and ++ operators are self-contained statements which affect the variable on which they are operating. So your num-- > 2 is the name as saying num > 2 followed by a num = num - 1, which compares the current value, then performs a mathematical operation and assigns the result of that operation to the variable.

Upvotes: 0

Related Questions