Reputation: 366
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
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
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
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