Chaining compound assignment operators in JavaScript

compound-assignment, ecmascript-5, javascript, side-effects

Solution

So I think if you break open the operation, you have:

s += (s += s);

s = s + (s += s);
s = s + (s = s + s);    // Can't actually have the "s = " part, it's really just "s + s"
s = s + (s + s);
s = s + s + s;

Which means the result should be "abcabcabc".

Problem

In C#, ``` string s = "abc"; s += (s += s); Console.WriteLine(s); ``` writes `abcabcabc` (http://ideone.com/pFNFX2). This is fine, because the C# specification explicitly says in section 7.16.2 that the operation is evaluated as x = x op y, except that x is evaluated only once. However, in reading the description of the compound assignment operator in section 11.3.2 of the ECMAScript 5.1 Language Specification, I see no such "only once" qualifier in the semantics of this operator. Instead, all I see is: - Let lref be the result of evaluating LeftHandSideExpression. - Let lval be GetValue(lref). - Let rref be the result of evaluating AssignmentExpression. - Let rval be GetValue(rref). - Let r be the result of applying operator @ to lval and rval. - Throw a SyntaxError exception if the following conditions are all true: (snipped) - Call PutValue(lref, r). - Return r. Therefore, it would appear (to me, anyway) that the following JavaScript code ``` var s = "abc"; s += (s += s); alert(s); ``` would alert `abcabcabcabc` (because of the PutValue on line 7 in the parenthesized expression), but, in Chrome 22 anyway, it alerts `abcabcabc`. So my question is: Am I misreading the specification, or is Chrome (V8 perhaps?) doing its own thing off-spec, so to speak?

Original source