6

次のように、破壊割り当てを使用して、タプルの要素をその場で交換することを考えました。

var a = [1,2];
[a[1], a[0]] = a;

ただし、これにより が得られ[1, 1]ます。

Babel はこれを次のようにコンパイルします。

a[1] = a[0];
a[0] = a[1];

これは次のようにコンパイルする必要があると思っていたでしょう

let tmp0 = a[0];
let tmp1 = a[1];
a[0] = tmp1;
a[1] = tmp0;

Traceur は、babel と同じように動作します。だから私はこれが指定された動作だと思いますか?

2 つの要素をその場で交換したい。唯一の方法です...

let tmp = a[0];
a[0] = a[1];
a[1] = tmp;

しかし、上記のことは、破壊的な代入が私がしなければならないことを回避できるはずのものだと思いました。

私は配列の 2 つの要素の順序を完全に逆にすることができるので、それは私の質問ではありません。のような単純なことを行うことができますa.push(a.shift())。これは、スワッピングがインプレースであるという基準を満たしています。

ここで私が最も興味を持っているのは、なぜ分解が本来あるべきように機能しないのかということです。

4

5 に答える 5

4

これは次のようにコンパイルする必要があると思っていたでしょう

let tmp0 = a[0];
let tmp1 = a[1];
a[0] = tmp1;
a[1] = tmp0;

いいえ、値は割り当てられる前に取得されません。aまたは、どちらも値の取得元の作成されたコピーではありません。配列への参照は 1 つだけです。あなたのコードはむしろ脱糖する

{
    const tmp = a;
    a[1] = tmp[0];
    a[0] = tmp[1]; // here, tmp[1] has the "wrong" value because a===tmp
}

または実際には、配列の左側の参照[…]が割り当てられている間、配列を反復する反復子に脱糖します。

于 2015-08-08T15:33:17.677 に答える
3

これはどう:

var a = [1,2];
a = a.reverse();
于 2015-08-07T17:38:01.370 に答える