32

Could somebody explain why the following functions give different results. The first does not seem to work, but the second does. I'm puzzled because I thought +=1 and ++ did the same thing.

(I'm not intending to actually use this code, it's just to demonstrate the difference).

/*function 1*/
function incrementIfZero1(base,element) {

    if (element == 0) {
        return base++;
    }
    else
    {
        return base;
    }
};


/*function 2*/
function incrementIfZero2(base,element) {

    if (element == 0) {
        return base+=1;
    }
    else
    {
        return base;
    }
};

incrementIfZero1(1,0) /* -> 1*/
incrementIfZero2(1,0) /* -> 2*/

Any help is very much appreciated.

Thanks,

Robin

[Edit:]

Thank you for your replies, it makes sense now. I had also tried the following statement, which resulted in the same thing as function 1:

return (base++)

I'm now surprised that this doesn't give the same result as function 2 - I would have expected the brackets to 'force' it to be evaluated before returning. Any idea why this is not the case?

RobinL
  • 11,009
  • 8
  • 48
  • 68
  • Thanks for your quick responses - please see the edit at the bottom for an additional and related question – RobinL Jun 21 '13 at 18:31

8 Answers8

32

when you return base++ it returns the value of base just before it gets incremented. You want to do ++base to make sure the increment happens first then it gets returned

otherwise ++ is the same as +=1

[edit] in response to your edit, i tried wrapping random statements in parentheses and most mathematical operators respond as expected, this incrementation seems to be exempt, likely because the syntax of pre-incrementation vs post-incrementation is highly intentional and the statement itself returns a specific value regardless of whether or not you wrap it in parentheses

Stephan
  • 16,509
  • 7
  • 35
  • 61
  • 3
    Thanks - I think I understand. So return (x++) is the same as return x++ because neither involve an assignment to x, so both of them say: "return x and then increment by one". Whereas return x+=1 says 'assign x+1 to x and return the resultant value of x'. – RobinL Jun 21 '13 at 18:44
  • 2
    @RobinL The *expression* `x++` returns `x` (to the `return` statement, which returns it from the function to the outside) then increments it . The expression `x+=1` increments `x`, then returns it. – bfavaretto Jun 21 '13 at 18:47
  • Although it may be obvious, for posterity's sake: **please** do not `return x++` or anything like unto it in production without clear explanation of the timing of the side effect! – Chris Collett Jun 23 '22 at 21:48
7

return (base++)

I'm now surprised that this doesn't give the same result as function 2 - I would have expected the brackets to 'force' it to be evaluated before returning. Any idea why this is not the case?

The increment operation is evaluated, regardless of the brackets. The catch here is that expressions in JavaScript always result in a value, which is then returned. For example, when you do var x = 2 + 2, 2 + 2 is evaluated, then "returned" to the = operator, which then assigns that value to x. The ++ postfix operator (as in base++) works differently: it does increment the variable preceding it, but the expression returns the value before incrementation. The prefix increment operator, on the other hand, works as you want, ++base returns the value after incrementing it.

Community
  • 1
  • 1
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • I know this is mostly redundant with other answers, but I hope it helps you understand why it behaves the way it does. – bfavaretto Jun 21 '13 at 18:39
  • Thanks for this answer - it did add useful additional information on why there's no difference between return x++ and return (x++). – RobinL Jun 21 '13 at 18:47
6
return base++;

Is post-increment. It increments the value held by base, and then returns the original value before the increment happened.

return base += 1;

Adds one to base, and then returns base. This is a pre-increment. This can also be written as:

return ++base;
Dan455
  • 352
  • 1
  • 9
5

You are returning base++. This is the postfix increment, thus, the increment is handled after the return. For this specific case, return ++base; would be correct

sonoftunk
  • 168
  • 1
  • 7
  • @JustinNiessner Actually it isn't. This is true for most (all?) languages that have the postfix notation. – Luke Jun 21 '13 at 18:37
  • @Luke - http://stackoverflow.com/questions/654715/in-java-how-does-a-post-increment-operator-act-in-a-return-statement (Java) and http://stackoverflow.com/questions/2380803/is-the-behavior-of-return-x-defined (C++) would beg to differ. I actually thought the same thing until I tried to double check for languages I don't use often. – Justin Niessner Jun 21 '13 at 18:47
  • @JustinNiessner [PHP also works this way](http://codepad.org/Cnlx0yPx). Maybe "most" was not the right word. "Some" would have been more appropriate. – Luke Jun 21 '13 at 19:13
4

Warning! There's a difference when two different types, a string and a number, are mutated using ++ and +=:

When count is a string, count += 1 seems to do type conversion and converts the 2nd number to a string, whereas count++ takes the string count argument, converts to a number, and increments by 1.

let count = process.argv[2]

while (count < 5) {
  console.log('Inside of the loop. Count is', count)
  count += 1 // NOT likely what you want! Now, try it with count++
}

console.log('Outside of loop. Count is', count)

Another example:

> let num = '2'
undefined
> num++
2
> num
3

// VS using +=

> let num2 = '2'
undefined
> num2 += 1
'21'
> num2
'21'
Danny
  • 3,982
  • 1
  • 34
  • 42
2

Just to clarify a little.

"variable += 1" is the equivalent of "variable = variable + 1". It is NOT the equivalent of variable++!

Something like variable++ can be used in-place, the former is an assignation.

Dany Caissy
  • 3,176
  • 15
  • 21
2

In The first function what happens is:

return base++; // at first base value is returned and then incremented.

In the 2nd Function :

return base+=1; //here the incrementation is done first and then the variable is returned.

shorthand assignment has higher priority i.e. it finishes it's job in that line itself

Usual Suspect
  • 601
  • 1
  • 8
  • 19
0

be carefull :

x = 1; y = (x++ * 10 + 1);

equal to :

y = 1 * 10 + 1 = 11

indeed :

x = 1; y = (++x * 10 + 1);

equal to :

y = 2 * 10 + 1 = 21;

to finish :

++x ;

or

x++ ;

there are not difference !