正如你所说,表达式是从左到右计算的,这意味着第一次遇到 a 时,它的值仍然是 5。这归结为:
var a = 5, b = 3;
a = ( a -( b = ( a = a+b ) - b ) );
a = 5 - (b = (a=(5+3)) - b);
a = 5 - (b = 8 - b);
a = 5 - 5; AND b = 5
在第二个中,a 值在赋值后被评估,因为它在右边
var a = 5, b = 3;
a = ( ( b = ( a = a+b ) - b ) - a );
a = ( ( b = 8 - b ) - a ); AND a = 8
a = ( 5 - 8 ); AND a = 8; AND b = 5;
a = - 3;
这一切都归结为操作数的评估顺序。
通常在第一种情况下,a 被评估为 5,然后b = ( a = a+b ) - b
被评估,并且仅在此评估期间 a 的值会发生变化,但不会向后移植。
在第二个例子中,( b = ( a = a+b ) - b )
首先求值,将 a 值更改为 8,然后求值 a,发现为 8
一个更简单的例子是:
var a = 5
a = a + (a = 2)
// a = 7
a
被评估为5,然后(a = 2)
被评估为2并且a被设置为2,然后5+2
被评估并且a被设置为7。
另一方面 :
var a = 5
a = (a = 2) + a
// a = 4
(a = 2)
被评估为 2 并且 a 设置为 2,然后a
被评估为 2,然后2+2
被评估并且 a 被设置为 4