I want to do something to a couple of variables using operators in quick succession. I don't think what I want to do is important as such; my question is more about the fundamentals of JavaScript evaluation.
In the three examples below, I try to use addition to change the values of two variables. However, not all perform as I (perhaps naïvely) expected.
OPERATIONS AS THREE SEPARATE STATEMENTS
var a = 9, b = 2; a += b; b += a; a += b; // a === 24, b === 13OPERATIONS SEPARATED BY COMMA OPERATOR
var a = 9, b = 2; a += b, b += a, a += b; // AS EXPECTED: a === 24, b === 13OPERATIONS IN ONE STATEMENT/EXPRESSION
var a = 9, b = 2; a += (b += (a += b)); // BUT HERE WE GET THIS: a === 22, b === 13
In the last example, b evaluates as expected, but a evaluates to a number two short of what appears in the first two examples.
I think that this is because everything in the parentheses returns the correct value but is finally added to the original value of a, i.e. 9, rather than the value suggested by (a += b) earlier in precedence which would be 11.
I have looked for why this might be in Flanagan's JavaScript: The Definitive Guide (6th ed.), (particularly under 4.11.1 "Assignment with operation") but found nothing there. Crockford doesn't seem to mention it explicitly in The Good Parts either. I've used various search terms to try to find more information on this behaviour. Can anyone tell me what this phenomenon is called or point me to some information on this behaviour (assuming it is expected) or what I might be doing wrong (assuming it's not)?
NB. I'm conscious that the parentheses in example 3 may be redundant since, as I understand it, assignment precedence goes from right-to-left anyway. But I thought having them there would make the example easier to talk about.
UPDATE
Judging by the answers below, I think my confusion over this issue actually stems from having absorbed a couple of paragraphs from the Flanagan book, possibly incorrectly:
In most cases, the expression:
a op= bwhere op is an operator, is equivalent to the expression:
a = a op bIn the first line, the expression
ais evaluated once. In the second, it is evaluated twice. The two cases differ only if sideaincludes side effects such as a function call or an increment operator. The following two assignments, for example, are not the same:data[i++] *= 2 data[i++] = data[i++] * 2
I took this to mean that my one line example should produce the same results as the other two, because:
- Flanagan mentions two evaluations occurring in
a = a op bas opposed to one, implying this is in fact different toa op= bwhereais not evaluated as anlvalon the right. - I assumed the assignment operator I used (e.g.
a += b) would count as a side-effect.
IMHO, I think Flanagan has made this confusing and it seems to contradict what's in the ECMAScript convention (as pasted below by pocka), but it could be my reading/misinterpretation. Is what he is saying incorrect or simply unclear? Or, is it just me?
a === 22if first evaluation wasa + brather thana += b. My question is about the behaviour given that this is an assignment toa, which seems to be forgotten by the time we get to the final assignment/evaluation.ato what's evaluated in parentheis, whereas prior two examples add b to a...then add the same amont on right. Nothing funky about it. I think it's one of those mind melt things where you think logic is flawed and want to delve deep into why....when it's your own mind playing tricks on you. We've all been there