0

As far as I've been led to understand, x++ is essentially a terser way of saying x = x + 1. So far, so clear. In front-end Javascript, I've occasionally seen ++x — I seem to remember from a jsPerf test I can no longer find (how does one Google ++ effectively?) that this somehow had a small performance benefit in a particular version of IE, and let it go at that.

However I've recently encountered something that speaks of a weird quirk in execution order (JS code):

var x = 1;
console.log(x++); // 1 (?!)
console.log(x);   // 2

…whereas

var x = 1;
console.log(++x); // 2 (what I would've expected)
console.log(x);   // 2

I can't get my head around this. How can we return the unmodified variable when the operation and assignment are within the parenthesis, and thus by all rights should be executed before console.log is even invoked, let alone executed and returned?

yasu
  • 1,374
  • 8
  • 16
Barney
  • 16,181
  • 5
  • 62
  • 76
  • 4
    That operator with the described behavior dates back *at least* to C, in the 1970's. – Pointy Dec 13 '12 at 16:26
  • 1
    The pdp-11 (and subsequently the VAX machines) had pre- and post-increment register-indirect addressing modes. Possibly the IBM 360/370 instruction set did too, along with various other processors through the years. – Pointy Dec 13 '12 at 16:27
  • 1
    The most effective search term for things like this is "ecmascript specification" – Paul Butcher Dec 13 '12 at 16:29
  • 1
    @PaulButcher Not according to all these other answers which suggest this is a generic feature rather than an ECMAscript quirk. It's Googling for special characters like `++` that doesn't seem to be possible. It appears to treat them as operators in the search query, and standard escape sequences have no apparent effect. – Barney Dec 13 '12 at 16:32
  • That has long been a flaw in Google. If you didn't already know they were called *increment operators*, there's no way to know what to Google. – kojiro Dec 13 '12 at 16:39
  • 2
    This particular operator is the same across many languages, but that is not necessarily true for all operators and all languages. If you are wondering how an operator behaves in a particular language, then the best way to find that out is to search for the specification of that language. You can then perform a text search for the operator in the specification document. You will then find sections 11.3 and 11.4 which give you googleable terms, if you want to know if other languages behave the same way. – Paul Butcher Dec 13 '12 at 16:42
  • Here is link to the spec: http://es5.github.com/#x11.3.1 and to the MDN article: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Arithmetic_Operators#.2B.2B_.28Increment.29 – Felix Kling Dec 13 '12 at 16:50

4 Answers4

5

Those are two different things

x++

is a post-increment. It returns x before the change but then changes it:

tmp = x;
x = x+1;
return tmp;

whereas

++x

is a pre-increment. It first changes x and returns the new value afterwards:

x = x+1;
return x;

The second one is also slightly faster as your compliler/interpreter doesn't need to create a temporary variable and copy the data across.

Nils Werner
  • 34,832
  • 7
  • 76
  • 98
  • 2
    *The second one is also slightly faster as your compliler/interpreter doesn't need to create a temporary variable and copy the data across.* [Not necessarily](http://stackoverflow.com/a/24887/418413) – kojiro Dec 13 '12 at 16:38
  • Thanks for the explanation of internal workings justifying the performance issue! But I'm still confused as to execution order — when exactly is the assignment back to the code-accessible variable made? For instance, wrapping the operation in parens still returns the unmodified variable. What's the minimum level of execution needed to force the assignment? – Barney Dec 13 '12 at 16:38
  • 1
    @Barney - read the link in my previous comment. It goes into depth about the operators, and explains how *postfix* requires a functional decomposition, but *prefix* may not. – kojiro Dec 13 '12 at 16:40
  • Thanks @kojiro — the nuts and bolts was what I was after. – Barney Dec 13 '12 at 17:10
2

x++ gets the value, then increments it.

++x increments the value, then gets it.

This is the behavior in every language I've used that supports these operators.

Waxen
  • 1,792
  • 2
  • 27
  • 27
1

Using ++ AFTER the variable increments the value after that line of code.

Likewise, using ++ BEFORE the variable increments the value before using it in that line of code.

Cool huh?

var x = 1;
x++;
console.log(x++); // 2 (?!)
console.log(x);   // 3
console.log(++x); // 4
console.log(x++); // 4
console.log(x);   // 5
jamis0n
  • 3,610
  • 8
  • 34
  • 50
1

You're talking about the difference between the pre- and post- increment operators. In the pre- case, the operation is essentially (x = x + 1; yield x), and in the second case it's (yield x; x = x + 1).

kojiro
  • 74,557
  • 19
  • 143
  • 201