Chaining compound assignment operators in JavaScript
-
14-07-2021 - |
سؤال
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?
المحلول
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".