11.13.2 Compound assignment op=

2010-05-22

Javascript supports a few so called "compound operators". These are shorthand assignment operators which first apply the compounded operator to the left and right operand and then store the result in the left operand. The @ represents the operator which is compounded with the = operator, which is one of * / % + - << >> >>> & ^ |

Code: (Meta Ecma)
function evaluate(LeftHandSideExpression @ = AssignmentExpression) {
var lref = evaluate(LeftHandSideExpression);
var lval = GetValue(lref);
var rref = evaluate(AssignmentExpression);
var rval = GetValue(rref);
var r = lval @ rval;
if (Type(rval) == 'reference' && IsStrictReference(lref) && Type(GetBase(lref)) == 'environmentRecord' && (GetReferencedName(lref) == 'eval' || GetReferencedName(lref) == 'arguments')) {
throw SyntaxError;
}
PutValue(lref, r);
return rval;
}

Note that the left hand side must not evaluate to an unresolvable reference. If it does, a ReferenceError is thrown on assignment (by PutValue). It may also not be a reference to a data property with [[Writable]] equal to false, or an accessor with [[Set]] equal to undefined, or to a non-existant property of an object whose [[Extensible]] set to false. In all these cases a TypeError is thrown (again, by or through PutValue).

The only difference between this algorithm and the regular assignment is the application of the compounded operator prior to assigning the result. Note that this happens before the possible throw, but because lval and rval are primitives, no side effects from this can be noticed (in fact, the operation might as well be placed after the condition...).