0

2 つの変数を交換するためにこのコードを評価してみましょう。

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

aの新しい値は である必要が3あり、 の値は であるb必要があると予想していました5。しかし、私は値を次のように取得しましたa = 0 and b = 5

EcmaScript の算術式を読みに行ったところ、これは左から右に評価されることがわかりました。(しかし、完全には明らかではありません)。

だから私はこれを試しました

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

今、私は得a = -3 and b = 5ました。誰かがなぜこれがこのように起こっているのか説明できますか?

4

5 に答える 5

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

各ステップで、1 人のオペレーターを処理します。

そして、これは式から作成されるツリーです。

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

次に、ツリーは下から上に処理されます。

于 2013-09-27T08:09:49.757 に答える
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

2番目のものでは、 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 の値が変更されますが、バックポートはされません。

2 番目の例で( 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 に設定されます

于 2013-09-27T08:05:15.673 に答える
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
于 2013-09-27T07:53:57.337 に答える
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

あなたが期待するように。

于 2013-09-27T08:07:31.903 に答える
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

于 2013-09-27T08:12:14.707 に答える