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 相同。所以我想这是指定的行为?

我想将这两个元素交换到位。所以是唯一的方法...

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

但我认为以上是解构分配应该让我避免做的事情。

我完全有能力颠倒数组中两个元素的顺序,所以这不是我的问题。我可以做一些简单的事情a.push(a.shift()),它符合就地交换的标准。

我最感兴趣的是为什么解构不像它应该的那样工作。

4

5 回答 5

7

我只是使用一个函数来做到这一点

let swap = ([a,b]) => [b,a];

swap([1,2]); // => [2,1]
于 2015-08-09T05:51:50.720 回答
4

我原以为这应该编译为

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

不,这些值在分配之前不会被检索。或者也不是a从中检索值的副本。只有一个对数组的引用;你的代码相当脱糖

{
    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 回答
3

作为替代方案,您可以使用slice

var a = [1,2];
[a[1], a[0]] = a.slice();
a; // [2,1]
于 2015-08-07T18:00:28.993 回答
2

这适用于支持解构的 Firefox:

(function () {
  "use strict";

  var a = [0, 1];
  [a[1], a[0]] = [a[0], a[1]];
  console.log(a);//[1, 0]
}());
于 2015-08-09T07:36:49.987 回答