4

在 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 节中对复合赋值运算符的描述时,我在该运算符的语义中没有看到这样的“仅一次”限定符。相反,我看到的是:

  1. 令 lref 为评估 LeftHandSideExpression 的结果。
  2. 令 lval 为 GetValue(lref)。
  3. 令 rref 为评估 AssignmentExpression 的结果。
  4. 设 rval 为 GetValue(rref)。
  5. 令 r 为将运算符 @ 应用于 lval 和 rval 的结果。
  6. 如果以下条件都为真,则抛出 SyntaxError 异常:(截断)
  7. 调用 PutValue(lref, r)。
  8. 返回 r。

因此,看起来(对我来说,无论如何)以下 JavaScript 代码

var s = "abc";
s += (s += s);
alert(s);

会提醒abcabcabcabc(因为括号表达式中第 7 行的 PutValue),但是无论如何在 Chrome 22 中,它都会提醒abcabcabc.

所以我的问题是:我是误读了规范,还是 Chrome(也许是 V8?)做​​自己的事情不符合规范,可以这么说?

4

1 回答 1

4

所以我认为如果你打开操作,你有:

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;

这意味着结果应该是“abcabcabc”。

于 2012-10-28T06:20:56.843 回答