有人可以解释javascript算术表达式是如何工作的吗?

时间:2013-09-27 07:44:36

标签: javascript arithmetic-expressions

让我们评估此代码以交换两个变量:

var a = 5, b = 3; 
a = ( a -( b = ( a = a+b ) - b ) );

我期待a的新值应为3b的值应为5。但我的值为a = 0 and b = 5;

我去阅读EcmaScript算术表达式,发现这将从左到右进行评估。 (但不完全清楚)。

所以我尝试了这个

var a = 5, b = 3; 
a = ( ( b = ( a = a+b ) - b ) - a );

现在我得到了a = -3 and b = 5。有人可以解释一下为什么会这样吗?

5 个答案:

答案 0 :(得分:2)

这是解释,我希望它很清楚,因为它不是那么明显。 JS和所有其他语言创建一个树来评估表达式。树根据位置和大括号为每个操作员分配权重。

首先,这是JS处理表达式的步骤:

Step 0. a = ( a - ( b = ( a = a+b ) - b ) );   a=5, b=3
Step 1.                   a = a+b              a=8, b=3
Step 2.             b = a - b                  a=8, b=5 
Step 3. a = a - b                              a=0, b=5

每一步都会处理一个操作员。

这是它从你的表达式创建的树:

    =
  /   \
 a     - 
     /    \
   a       =
          /  \   
         b    -            
             / \
            =   b
           /  \
          a    +
              / \
             a   b

然后从下到上处理树。

答案 1 :(得分:1)

var a = 5, b = 3;
a = ( ( b = ( a = a+b ) - b ) - a );

它将以这种方式运作。

a = a + b //8
b = a - b //8-3=5
a = b - a //5-8=-3

答案 2 :(得分:1)

正如你所说,表达式从左到右进行评估,这意味着第一次遇到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,并且仅在此评估期间更改值,但不会向后移植。

在第二个示例中,首先评估( 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

答案 3 :(得分:0)

a = ( a -( b = ( a = a+b ) - b ) ) 

与此类似

a = ( 5 -( b = ( a = 5+3 ) - 3 ) ) // a = 8
// a = ( 5 - ( b = 8 - 3 ) ) // b = 5
// a = ( 5 - 5 ) // a = 0

意味着它将使用相同的初始值替换=左侧的a和b, 它与此序列不相似

a = a+b; // a = 8
b = a-b; // b = 5
a = a-b; // a = 3

如你所料。

答案 4 :(得分:0)

var a = 5, b = 3; 
a = ( a -( b = ( a = a+b ) - b ) );

1)a = a(5) - (表达的其余部分,其中2部分将很快计算)

2)b =(a = a + b //并且仍未计算) - b(为3,因为新b尚未更改)

3)a = 5(a)+ 3(b)= 8

4)b(我们回到第2点)= 8(新a) - 3(旧b)= 5

5)a(点1)= 5(旧a)-5(新b)= 0

新a = 0,新b = 5

var a = 5, b = 3; 
a = ( ( b = ( a = a+b ) - b ) - a );

1)b =(a = a + b)-3(b)

2)a = 5(a)+ 3(b)= 8

3)b = 8(新a)-3(旧b)= 5

4)a(最终)= 5(新b) - 8(新a)= -3

新a = -3,新b = 5

我希望它是可读的:D