在 C# 中,
string s = "abc";
s += (s += s);
Console.WriteLine(s);
写道abcabcabc
(http://ideone.com/pFNFX2)。这很好,因为 C# 规范在第 7.16.2 节中明确指出
该操作被评估为 x = x op y,除了 x 只被评估一次。
但是,在阅读 ECMAScript 5.1 语言规范第 11.3.2 节中对复合赋值运算符的描述时,我在该运算符的语义中没有看到这样的“仅一次”限定符。相反,我看到的是:
- 令 lref 为评估 LeftHandSideExpression 的结果。
- 令 lval 为 GetValue(lref)。
- 令 rref 为评估 AssignmentExpression 的结果。
- 设 rval 为 GetValue(rref)。
- 令 r 为将运算符 @ 应用于 lval 和 rval 的结果。
- 如果以下条件都为真,则抛出 SyntaxError 异常:(截断)
- 调用 PutValue(lref, r)。
- 返回 r。
因此,看起来(对我来说,无论如何)以下 JavaScript 代码
var s = "abc";
s += (s += s);
alert(s);
会提醒abcabcabcabc
(因为括号表达式中第 7 行的 PutValue),但是无论如何在 Chrome 22 中,它都会提醒abcabcabc
.
所以我的问题是:我是误读了规范,还是 Chrome(也许是 V8?)做自己的事情不符合规范,可以这么说?